SGF-535 - Allow both SpEL and property placeholder expressions to be used in the locators/servers attributes of the <gfe:pool> XML namespace element.
This commit is contained in:
@@ -19,6 +19,13 @@ package org.springframework.data.gemfire.client;
|
||||
import java.net.InetSocketAddress;
|
||||
import java.util.List;
|
||||
|
||||
import com.gemstone.gemfire.cache.client.ClientCache;
|
||||
import com.gemstone.gemfire.cache.client.Pool;
|
||||
import com.gemstone.gemfire.cache.client.PoolFactory;
|
||||
import com.gemstone.gemfire.cache.client.PoolManager;
|
||||
import com.gemstone.gemfire.cache.query.QueryService;
|
||||
import com.gemstone.gemfire.distributed.DistributedSystem;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
import org.springframework.beans.BeansException;
|
||||
@@ -35,17 +42,10 @@ import org.springframework.data.gemfire.util.DistributedSystemUtils;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
import com.gemstone.gemfire.cache.client.ClientCache;
|
||||
import com.gemstone.gemfire.cache.client.Pool;
|
||||
import com.gemstone.gemfire.cache.client.PoolFactory;
|
||||
import com.gemstone.gemfire.cache.client.PoolManager;
|
||||
import com.gemstone.gemfire.cache.query.QueryService;
|
||||
import com.gemstone.gemfire.distributed.DistributedSystem;
|
||||
|
||||
/**
|
||||
* FactoryBean for easy declaration and configuration of a GemFire {@link Pool}. If a new {@link Pool} is created,
|
||||
* its lifecycle is bound to that of this declaring factory.
|
||||
*
|
||||
*
|
||||
* Note, if a {@link Pool} having the configured name already exists, then the existing {@link Pool} will be returned
|
||||
* as is without any modifications and its lifecycle will be unaffected by this factory.
|
||||
*
|
||||
@@ -596,5 +596,4 @@ public class PoolFactoryBean implements FactoryBean<Pool>, InitializingBean, Dis
|
||||
public void setThreadLocalConnections(boolean threadLocalConnections) {
|
||||
this.threadLocalConnections = threadLocalConnections;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -16,11 +16,8 @@
|
||||
|
||||
package org.springframework.data.gemfire.config;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import org.springframework.beans.factory.BeanDefinitionStoreException;
|
||||
import org.springframework.beans.factory.config.BeanDefinition;
|
||||
@@ -42,21 +39,24 @@ import org.springframework.util.xml.DomUtils;
|
||||
import org.w3c.dom.Element;
|
||||
|
||||
/**
|
||||
* Parser for GFE <pool;gt; bean definitions.
|
||||
*
|
||||
* Parser for <gfe:pool> bean definitions.
|
||||
*
|
||||
* @author Costin Leau
|
||||
* @author David Turanski
|
||||
* @author John Blum
|
||||
* @see org.springframework.beans.factory.config.BeanDefinition
|
||||
* @see org.springframework.beans.factory.support.BeanDefinitionBuilder
|
||||
* @see org.springframework.beans.factory.support.BeanDefinitionRegistry
|
||||
* @see org.springframework.beans.factory.xml.AbstractSingleBeanDefinitionParser
|
||||
* @see org.springframework.data.gemfire.client.PoolFactoryBean
|
||||
*/
|
||||
class PoolParser extends AbstractSingleBeanDefinitionParser {
|
||||
|
||||
static final AtomicBoolean INFRASTRUCTURE_REGISTRATION = new AtomicBoolean(false);
|
||||
static final AtomicBoolean INFRASTRUCTURE_COMPONENTS_REGISTERED = new AtomicBoolean(false);
|
||||
|
||||
protected static final int DEFAULT_LOCATOR_PORT = GemfireUtils.DEFAULT_LOCATOR_PORT;
|
||||
protected static final int DEFAULT_SERVER_PORT = GemfireUtils.DEFAULT_CACHE_SERVER_PORT;
|
||||
|
||||
protected static final Pattern PROPERTY_PLACEHOLDER_PATTERN = Pattern.compile("\\$\\{.+\\}");
|
||||
|
||||
protected static final String DEFAULT_HOST = "localhost";
|
||||
protected static final String HOST_ATTRIBUTE_NAME = "host";
|
||||
protected static final String LOCATOR_ELEMENT_NAME = "locator";
|
||||
@@ -66,8 +66,8 @@ class PoolParser extends AbstractSingleBeanDefinitionParser {
|
||||
protected static final String SERVERS_ATTRIBUTE_NAME = "servers";
|
||||
|
||||
/* (non-Javadoc) */
|
||||
static void registerSupportingInfrastructureComponents(ParserContext parserContext) {
|
||||
if (INFRASTRUCTURE_REGISTRATION.compareAndSet(false, true)) {
|
||||
static void registerInfrastructureComponents(ParserContext parserContext) {
|
||||
if (INFRASTRUCTURE_COMPONENTS_REGISTERED.compareAndSet(false, true)) {
|
||||
AbstractBeanDefinition beanDefinition = BeanDefinitionBuilder
|
||||
.genericBeanDefinition(ClientRegionAndPoolBeanFactoryPostProcessor.class)
|
||||
.setRole(BeanDefinition.ROLE_INFRASTRUCTURE)
|
||||
@@ -85,7 +85,7 @@ class PoolParser extends AbstractSingleBeanDefinitionParser {
|
||||
@Override
|
||||
protected void doParse(Element element, ParserContext parserContext, BeanDefinitionBuilder builder) {
|
||||
|
||||
registerSupportingInfrastructureComponents(parserContext);
|
||||
registerInfrastructureComponents(parserContext);
|
||||
|
||||
ParsingUtils.setPropertyValue(element, builder, "free-connection-timeout");
|
||||
ParsingUtils.setPropertyValue(element, builder, "idle-timeout");
|
||||
@@ -124,13 +124,13 @@ class PoolParser extends AbstractSingleBeanDefinitionParser {
|
||||
}
|
||||
}
|
||||
|
||||
locators.addAll(parseLocators(element, getRegistry(parserContext)));
|
||||
servers.addAll(parseServers(element, getRegistry(parserContext)));
|
||||
boolean locatorsSet = parseLocators(element, getRegistry(parserContext));
|
||||
boolean serversSet = parseServers(element, getRegistry(parserContext));
|
||||
|
||||
// NOTE if neither Locators nor Servers were specified, then setup a connection to a Server
|
||||
// running on localhost, listening on the default CacheServer port, 40404
|
||||
if (childElements.isEmpty() && !hasAttributes(element, LOCATORS_ATTRIBUTE_NAME, SERVERS_ATTRIBUTE_NAME)) {
|
||||
servers.add(buildConnection(DEFAULT_HOST, String.valueOf(DEFAULT_SERVER_PORT), false));
|
||||
// NOTE: if neither Locators nor Servers were configured, then setup a connection to a Server
|
||||
// running on localhost, listening on the default CacheServer port 40404
|
||||
if (childElements.isEmpty() && !(locatorsSet || serversSet)) {
|
||||
servers.add(buildConnection(DEFAULT_HOST, String.valueOf(DEFAULT_SERVER_PORT), true));
|
||||
}
|
||||
|
||||
if (!locators.isEmpty()) {
|
||||
@@ -142,43 +142,15 @@ class PoolParser extends AbstractSingleBeanDefinitionParser {
|
||||
}
|
||||
}
|
||||
|
||||
/* (non-Javadoc) */
|
||||
boolean hasAttributes(Element element, String... attributeNames) {
|
||||
for (String attributeName : attributeNames) {
|
||||
if (element.hasAttribute(attributeName)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/* (non-Javadoc) */
|
||||
boolean isPropertyPlaceholder(String value) {
|
||||
return PROPERTY_PLACEHOLDER_PATTERN.matcher(value).matches();
|
||||
}
|
||||
|
||||
/* (non-Javadoc) */
|
||||
BeanDefinitionRegistry getRegistry(ParserContext parserContext) {
|
||||
return parserContext.getRegistry();
|
||||
}
|
||||
|
||||
/* (non-Javadoc) */
|
||||
BeanDefinition buildConnections(String propertyPlaceholder, boolean server) {
|
||||
BeanDefinitionBuilder connectionEndpointListBuilder = BeanDefinitionBuilder.genericBeanDefinition(
|
||||
ConnectionEndpointList.class);
|
||||
|
||||
connectionEndpointListBuilder.setFactoryMethod("parse");
|
||||
connectionEndpointListBuilder.addConstructorArgValue(defaultPort(null, server));
|
||||
connectionEndpointListBuilder.addConstructorArgValue(propertyPlaceholder);
|
||||
|
||||
return connectionEndpointListBuilder.getBeanDefinition();
|
||||
}
|
||||
|
||||
/* (non-Javadoc) */
|
||||
BeanDefinition buildConnection(String host, String port, boolean server) {
|
||||
BeanDefinitionBuilder connectionEndpointBuilder = BeanDefinitionBuilder.genericBeanDefinition(
|
||||
ConnectionEndpoint.class);
|
||||
BeanDefinitionBuilder connectionEndpointBuilder =
|
||||
BeanDefinitionBuilder.genericBeanDefinition(ConnectionEndpoint.class);
|
||||
|
||||
connectionEndpointBuilder.addConstructorArgValue(defaultHost(host));
|
||||
connectionEndpointBuilder.addConstructorArgValue(defaultPort(port, server));
|
||||
@@ -186,6 +158,18 @@ class PoolParser extends AbstractSingleBeanDefinitionParser {
|
||||
return connectionEndpointBuilder.getBeanDefinition();
|
||||
}
|
||||
|
||||
/* (non-Javadoc) */
|
||||
BeanDefinition buildConnections(String expression, boolean server) {
|
||||
BeanDefinitionBuilder connectionEndpointListBuilder =
|
||||
BeanDefinitionBuilder.genericBeanDefinition(ConnectionEndpointList.class);
|
||||
|
||||
connectionEndpointListBuilder.setFactoryMethod("parse");
|
||||
connectionEndpointListBuilder.addConstructorArgValue(defaultPort(null, server));
|
||||
connectionEndpointListBuilder.addConstructorArgValue(expression);
|
||||
|
||||
return connectionEndpointListBuilder.getBeanDefinition();
|
||||
}
|
||||
|
||||
/* (non-Javadoc) */
|
||||
String defaultHost(String host) {
|
||||
return (StringUtils.hasText(host) ? host : DEFAULT_HOST);
|
||||
@@ -197,51 +181,6 @@ class PoolParser extends AbstractSingleBeanDefinitionParser {
|
||||
: String.valueOf(DEFAULT_LOCATOR_PORT)));
|
||||
}
|
||||
|
||||
/* (non-Javadoc) */
|
||||
List<BeanDefinition> parseConnections(String hostPortCommaDelimitedList, boolean server) {
|
||||
List<BeanDefinition> connections = Collections.emptyList();
|
||||
|
||||
if (StringUtils.hasText(hostPortCommaDelimitedList)) {
|
||||
String[] hostsPorts = hostPortCommaDelimitedList.split(",");
|
||||
|
||||
connections = new ArrayList<BeanDefinition>(hostsPorts.length);
|
||||
|
||||
for (String hostPort : hostsPorts) {
|
||||
connections.add(parseConnection(hostPort, server));
|
||||
}
|
||||
}
|
||||
|
||||
return connections;
|
||||
}
|
||||
|
||||
/* (non-Javadoc) */
|
||||
BeanDefinition parseConnection(String hostPort, boolean server) {
|
||||
String host = hostPort.trim();
|
||||
String port = defaultPort(null, server);
|
||||
|
||||
int portIndex = host.indexOf('[');
|
||||
|
||||
if (portIndex > -1) {
|
||||
port = parseDigits(host.substring(portIndex)).trim();
|
||||
host = host.substring(0, portIndex).trim();
|
||||
}
|
||||
|
||||
return buildConnection(host, port, server);
|
||||
}
|
||||
|
||||
/* (non-Javadoc) */
|
||||
String parseDigits(String value) {
|
||||
StringBuilder digits = new StringBuilder();
|
||||
|
||||
for (char character : value.toCharArray()) {
|
||||
if (Character.isDigit(character)) {
|
||||
digits.append(character);
|
||||
}
|
||||
}
|
||||
|
||||
return digits.toString();
|
||||
}
|
||||
|
||||
/* (non-Javadoc) */
|
||||
BeanDefinition parseLocator(Element element) {
|
||||
return buildConnection(element.getAttribute(HOST_ATTRIBUTE_NAME),
|
||||
@@ -249,14 +188,12 @@ class PoolParser extends AbstractSingleBeanDefinitionParser {
|
||||
}
|
||||
|
||||
/* (non-Javadoc) */
|
||||
List<BeanDefinition> parseLocators(Element element, BeanDefinitionRegistry registry) {
|
||||
List<BeanDefinition> beanDefinitions = Collections.emptyList();
|
||||
|
||||
boolean parseLocators(Element element, BeanDefinitionRegistry registry) {
|
||||
String locatorsAttributeValue = element.getAttribute(LOCATORS_ATTRIBUTE_NAME);
|
||||
|
||||
if (isPropertyPlaceholder(locatorsAttributeValue)) {
|
||||
BeanDefinitionBuilder addLocatorsMethodInvokingBeanBuilder = BeanDefinitionBuilder.genericBeanDefinition(
|
||||
MethodInvokingBean.class);
|
||||
if (StringUtils.hasText(locatorsAttributeValue)) {
|
||||
BeanDefinitionBuilder addLocatorsMethodInvokingBeanBuilder =
|
||||
BeanDefinitionBuilder.genericBeanDefinition(MethodInvokingBean.class);
|
||||
|
||||
addLocatorsMethodInvokingBeanBuilder.addPropertyReference("targetObject", resolveDereferencedId(element));
|
||||
addLocatorsMethodInvokingBeanBuilder.addPropertyValue("targetMethod", "addLocators");
|
||||
@@ -267,12 +204,11 @@ class PoolParser extends AbstractSingleBeanDefinitionParser {
|
||||
addLocatorsMethodInvokingBeanBuilder.getBeanDefinition();
|
||||
|
||||
BeanDefinitionReaderUtils.registerWithGeneratedName(addLocatorsMethodInvokingBean, registry);
|
||||
}
|
||||
else {
|
||||
beanDefinitions = parseConnections(locatorsAttributeValue, false);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return beanDefinitions;
|
||||
return false;
|
||||
}
|
||||
|
||||
/* (non-Javadoc) */
|
||||
@@ -282,14 +218,12 @@ class PoolParser extends AbstractSingleBeanDefinitionParser {
|
||||
}
|
||||
|
||||
/* (non-Javadoc) */
|
||||
List<BeanDefinition> parseServers(Element element, BeanDefinitionRegistry registry) {
|
||||
List<BeanDefinition> beanDefinitions = Collections.emptyList();
|
||||
|
||||
boolean parseServers(Element element, BeanDefinitionRegistry registry) {
|
||||
String serversAttributeValue = element.getAttribute(SERVERS_ATTRIBUTE_NAME);
|
||||
|
||||
if (isPropertyPlaceholder(serversAttributeValue)) {
|
||||
BeanDefinitionBuilder addServersMethodInvokingBeanBuilder = BeanDefinitionBuilder.genericBeanDefinition(
|
||||
MethodInvokingBean.class);
|
||||
if (StringUtils.hasText(serversAttributeValue)) {
|
||||
BeanDefinitionBuilder addServersMethodInvokingBeanBuilder =
|
||||
BeanDefinitionBuilder.genericBeanDefinition(MethodInvokingBean.class);
|
||||
|
||||
addServersMethodInvokingBeanBuilder.addPropertyReference("targetObject", resolveDereferencedId(element));
|
||||
addServersMethodInvokingBeanBuilder.addPropertyValue("targetMethod", "addServers");
|
||||
@@ -300,12 +234,11 @@ class PoolParser extends AbstractSingleBeanDefinitionParser {
|
||||
addServersMethodInvokingBeanBuilder.getBeanDefinition();
|
||||
|
||||
BeanDefinitionReaderUtils.registerWithGeneratedName(addServersMethodInvokingBean, registry);
|
||||
}
|
||||
else {
|
||||
beanDefinitions = parseConnections(serversAttributeValue, true);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return beanDefinitions;
|
||||
return false;
|
||||
}
|
||||
|
||||
/* (non-Javadoc) */
|
||||
@@ -333,5 +266,4 @@ class PoolParser extends AbstractSingleBeanDefinitionParser {
|
||||
|
||||
return id;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -18,6 +18,7 @@ package org.springframework.data.gemfire.support;
|
||||
|
||||
import java.net.InetSocketAddress;
|
||||
|
||||
import org.springframework.data.gemfire.util.SpringUtils;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.util.ObjectUtils;
|
||||
import org.springframework.util.StringUtils;
|
||||
@@ -126,12 +127,17 @@ public class ConnectionEndpoint implements Cloneable, Comparable<ConnectionEndpo
|
||||
* @see ConnectionEndpoint#DEFAULT_HOST
|
||||
*/
|
||||
public ConnectionEndpoint(String host, int port) {
|
||||
Assert.isTrue(port >= 0 && port <= 65535, String.format("port number (%1$d) must be between 0 and 65535", port));
|
||||
Assert.isTrue(isValidPort(port), String.format("port number [%d] must be between 0 and 65535", port));
|
||||
|
||||
this.host = (StringUtils.hasText(host) ? host : DEFAULT_HOST);
|
||||
this.host = SpringUtils.defaultIfEmpty(host, DEFAULT_HOST);
|
||||
this.port = port;
|
||||
}
|
||||
|
||||
/* (non-Javadoc) */
|
||||
private boolean isValidPort(int port) {
|
||||
return (port >= 0 && port <= 65535);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the host in this ConnectionEndpoint.
|
||||
*
|
||||
@@ -208,5 +214,4 @@ public class ConnectionEndpoint implements Cloneable, Comparable<ConnectionEndpo
|
||||
public String toString() {
|
||||
return String.format("%1$s[%2$d]", getHost(), getPort());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -26,7 +26,6 @@ import java.util.List;
|
||||
|
||||
import org.springframework.data.gemfire.util.ArrayUtils;
|
||||
import org.springframework.data.gemfire.util.CollectionUtils;
|
||||
import org.springframework.data.gemfire.util.SpringUtils;
|
||||
|
||||
/**
|
||||
* The ConnectionEndpointList class is an Iterable collection of ConnectionEndpoint objects.
|
||||
@@ -34,6 +33,7 @@ import org.springframework.data.gemfire.util.SpringUtils;
|
||||
* @author John Blum
|
||||
* @see java.lang.Iterable
|
||||
* @see java.net.InetSocketAddress
|
||||
* @see java.util.AbstractList
|
||||
* @see org.springframework.data.gemfire.support.ConnectionEndpoint
|
||||
* @since 1.6.3
|
||||
*/
|
||||
@@ -97,7 +97,8 @@ public class ConnectionEndpointList extends AbstractList<ConnectionEndpoint> {
|
||||
* @see org.springframework.data.gemfire.support.ConnectionEndpoint#parse(String, int)
|
||||
*/
|
||||
public static ConnectionEndpointList parse(int defaultPort, String... hostsPorts) {
|
||||
List<ConnectionEndpoint> connectionEndpoints = new ArrayList<ConnectionEndpoint>(hostsPorts.length);
|
||||
List<ConnectionEndpoint> connectionEndpoints = new ArrayList<ConnectionEndpoint>(
|
||||
ArrayUtils.length((Object) hostsPorts));
|
||||
|
||||
for (String hostPort : ArrayUtils.nullSafeArray(hostsPorts, String.class)) {
|
||||
connectionEndpoints.add(ConnectionEndpoint.parse(hostPort, defaultPort));
|
||||
@@ -139,7 +140,7 @@ public class ConnectionEndpointList extends AbstractList<ConnectionEndpoint> {
|
||||
/* (non-Javadoc) */
|
||||
@Override
|
||||
public boolean add(ConnectionEndpoint connectionEndpoint) {
|
||||
return (add(SpringUtils.toArray(connectionEndpoint)) == this);
|
||||
return (add(ArrayUtils.asArray(connectionEndpoint)) == this);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -334,5 +335,4 @@ public class ConnectionEndpointList extends AbstractList<ConnectionEndpoint> {
|
||||
public String toString() {
|
||||
return connectionEndpoints.toString();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -14,6 +14,7 @@
|
||||
package org.springframework.data.gemfire.util;
|
||||
|
||||
import java.lang.reflect.Array;
|
||||
import java.util.Arrays;
|
||||
|
||||
/**
|
||||
* The ArrayUtils class is a utility class for working with Object arrays.
|
||||
@@ -24,6 +25,44 @@ import java.lang.reflect.Array;
|
||||
*/
|
||||
public abstract class ArrayUtils {
|
||||
|
||||
/**
|
||||
* Returns the given varargs {@code element} as an array.
|
||||
*
|
||||
* @param <T> Class type of the elements.
|
||||
* @param elements variable list of arguments to return as an array.
|
||||
* @return an arry for the given varargs {@code elements}.
|
||||
*/
|
||||
public static <T> T[] asArray(T... elements) {
|
||||
return elements;
|
||||
}
|
||||
|
||||
/**
|
||||
* Null-safe method to return the first element in the array or {@literal null}
|
||||
* if the array is {@literal null} or empty.
|
||||
*
|
||||
* @param <T> Class type of the array elements.
|
||||
* @param array the array from which to extract the first element.
|
||||
* @return the first element in the array or {@literal null} if the array is null or empty.
|
||||
* @see #getFirst(Object[], Object)
|
||||
*/
|
||||
public static <T> T getFirst(T... array) {
|
||||
return getFirst(array, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Null-safe method to return the first element in the array or the {@code defaultValue}
|
||||
* if the array is {@literal null} or empty.
|
||||
*
|
||||
* @param <T> Class type of the array elements.
|
||||
* @param array the array from which to extract the first element.
|
||||
* @param defaultValue value to return if the array is {@literal null} or empty.
|
||||
* @return the first element in the array or {@code defaultValue} if the array is {@literal null} or empty.
|
||||
* @see #getFirst(Object[], Object)
|
||||
*/
|
||||
public static <T> T getFirst(T[] array, T defaultValue) {
|
||||
return (isEmpty(array) ? defaultValue : array[0]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Insert an element into the given array at position (index). The element is inserted at the given position
|
||||
* and all elements afterwards are moved to the right.
|
||||
@@ -119,4 +158,17 @@ public abstract class ArrayUtils {
|
||||
|
||||
return newArray;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sort the array of elements according to the elements natural ordering.
|
||||
*
|
||||
* @param <T> {@link Comparable} class type of the array elements.
|
||||
* @param array array of elements to sort.
|
||||
* @return the sorted array of elements.
|
||||
* @see java.util.Arrays#sort(Object[])
|
||||
*/
|
||||
public static <T extends Comparable<T>> T[] sort(T[] array) {
|
||||
Arrays.sort(array);
|
||||
return array;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
|
||||
package org.springframework.data.gemfire.util;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.Enumeration;
|
||||
@@ -26,12 +27,16 @@ import java.util.Map;
|
||||
import java.util.NoSuchElementException;
|
||||
import java.util.Set;
|
||||
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
/**
|
||||
* The CollectionUtils class is a utility class for working with Java Collections Framework and classes.
|
||||
*
|
||||
* @author John Blum
|
||||
* @see java.util.Collection
|
||||
* @see java.util.Collections
|
||||
* @see java.util.Enumeration
|
||||
* @see java.util.Iterator
|
||||
* @see java.util.List
|
||||
* @see java.util.Map
|
||||
* @see java.util.Set
|
||||
@@ -97,6 +102,7 @@ public abstract class CollectionUtils extends org.springframework.util.Collectio
|
||||
* @return the given {@link Collection} if not null or return an empty {@link Collection}
|
||||
* (implemented with {@link List}).
|
||||
* @see java.util.Collections#emptyList()
|
||||
* @see java.util.Collection
|
||||
*/
|
||||
public static <T> Collection<T> nullSafeCollection(Collection<T> collection) {
|
||||
return (collection != null ? collection : Collections.<T>emptyList());
|
||||
@@ -140,6 +146,7 @@ public abstract class CollectionUtils extends org.springframework.util.Collectio
|
||||
* @param list {@link List} to evaluate.
|
||||
* @return the given {@link List} if not null or an empty {@link List}.
|
||||
* @see java.util.Collections#emptyList()
|
||||
* @see java.util.List
|
||||
*/
|
||||
public static <T> List<T> nullSafeList(List<T> list) {
|
||||
return (list != null ? list : Collections.<T>emptyList());
|
||||
@@ -154,6 +161,7 @@ public abstract class CollectionUtils extends org.springframework.util.Collectio
|
||||
* @param map {@link Map} to evaluate.
|
||||
* @return the given {@link Map} if not null or an empty {@link Map}.
|
||||
* @see java.util.Collections#emptyMap()
|
||||
* @see java.util.Map
|
||||
*/
|
||||
public static <K, V> Map<K, V> nullSafeMap(Map<K, V> map) {
|
||||
return (map != null ? map : Collections.<K, V>emptyMap());
|
||||
@@ -167,8 +175,48 @@ public abstract class CollectionUtils extends org.springframework.util.Collectio
|
||||
* @param set {@link Set} to evaluate.
|
||||
* @return the given {@link Set} if not null or an empty {@link Set}.
|
||||
* @see java.util.Collections#emptySet()
|
||||
* @see java.util.Set
|
||||
*/
|
||||
public static <T> Set<T> nullSafeSet(Set<T> set) {
|
||||
return (set != null ? set : Collections.<T>emptySet());
|
||||
}
|
||||
|
||||
/**
|
||||
* Sors the elements of the given {@link List} by their natural, {@link Comparable} ordering.
|
||||
*
|
||||
* @param <T> {@link Comparable} class type of the collection elements.
|
||||
* @param list {@link List} of elements to sort.
|
||||
* @return the {@link List} sorted.
|
||||
* @see java.util.Collections#sort(List)
|
||||
* @see java.util.List
|
||||
*/
|
||||
public static <T extends Comparable<T>> List<T> sort(List<T> list) {
|
||||
Collections.sort(list);
|
||||
return list;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a sub-list of elements from the given {@link List} based on the provided {@code indices}.
|
||||
*
|
||||
* @param <T> Class type of the elements in the list.
|
||||
* @param source {@link List} from which the elements of the sub-list is constructed.
|
||||
* @param indices array of indexes in the {@code source} {@link List} to the elements
|
||||
* used to construct the sub-list.
|
||||
* @return a sub-list of elements from the given {@link List} based on the provided {@code indices}.
|
||||
* @throws IndexOutOfBoundsException if the array of indexes contains an index that is not within
|
||||
* the bounds of the list.
|
||||
* @throws NullPointerException if either the list or indexes are null.
|
||||
* @see java.util.List
|
||||
*/
|
||||
public static <T> List<T> subList(List<T> source, int... indices) {
|
||||
Assert.notNull(source, "List must not be null");
|
||||
|
||||
List<T> result = new ArrayList<T>(indices.length);
|
||||
|
||||
for (int index : indices) {
|
||||
result.add(source.get(index));
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -17,10 +17,6 @@
|
||||
|
||||
package org.springframework.data.gemfire.util;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
import org.springframework.beans.factory.BeanFactory;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
@@ -31,6 +27,7 @@ import org.springframework.util.StringUtils;
|
||||
* @since 1.8.0
|
||||
*/
|
||||
@SuppressWarnings("unused")
|
||||
// TODO rename this utiltiy class using a more intuitive, meaningful name
|
||||
public abstract class SpringUtils {
|
||||
|
||||
/* (non-Javadoc) */
|
||||
@@ -47,22 +44,4 @@ public abstract class SpringUtils {
|
||||
public static String dereferenceBean(String beanName) {
|
||||
return String.format("%1$s%2$s", BeanFactory.FACTORY_BEAN_PREFIX, beanName);
|
||||
}
|
||||
|
||||
/* (non-Javadoc) */
|
||||
public static <T> T[] toArray(T... array) {
|
||||
return array;
|
||||
}
|
||||
|
||||
/* (non-Javadoc) */
|
||||
public static <T extends Comparable<T>> T[] sort(T[] array) {
|
||||
Arrays.sort(array);
|
||||
return array;
|
||||
}
|
||||
|
||||
/* (non-Javadoc) */
|
||||
public static <T extends Comparable<T>> List<T> sort(List<T> list) {
|
||||
Collections.sort(list);
|
||||
return list;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user