Polishing
This commit is contained in:
parent
838855b1aa
commit
6051ea8ae3
|
|
@ -17,31 +17,32 @@
|
|||
package org.springframework.expression;
|
||||
|
||||
/**
|
||||
* Instances of a type comparator should be able to compare pairs of objects for equality,
|
||||
* the specification of the return value is the same as for {@link Comparable}.
|
||||
* Instances of a type comparator should be able to compare pairs of objects for equality.
|
||||
* The specification of the return value is the same as for {@link java.lang.Comparable}.
|
||||
*
|
||||
* @author Andy Clement
|
||||
* @since 3.0
|
||||
* @see java.lang.Comparable
|
||||
*/
|
||||
public interface TypeComparator {
|
||||
|
||||
/**
|
||||
* Compare two objects.
|
||||
* Return {@code true} if the comparator can compare these two objects.
|
||||
* @param firstObject the first object
|
||||
* @param secondObject the second object
|
||||
* @return 0 if they are equal, <0 if the first is smaller than the second, or >0 if
|
||||
* the first is larger than the second
|
||||
* @throws EvaluationException if a problem occurs during comparison (or they are not
|
||||
* comparable)
|
||||
*/
|
||||
int compare(Object firstObject, Object secondObject) throws EvaluationException;
|
||||
|
||||
/**
|
||||
* Return true if the comparator can compare these two objects
|
||||
* @param firstObject the first object
|
||||
* @param secondObject the second object
|
||||
* @return true if the comparator can compare these objects
|
||||
* @return {@code true} if the comparator can compare these objects
|
||||
*/
|
||||
boolean canCompare(Object firstObject, Object secondObject);
|
||||
|
||||
/**
|
||||
* Compare two given objects.
|
||||
* @param firstObject the first object
|
||||
* @param secondObject the second object
|
||||
* @return 0 if they are equal, <0 if the first is smaller than the second,
|
||||
* or >0 if the first is larger than the second
|
||||
* @throws EvaluationException if a problem occurs during comparison
|
||||
* (or if they are not comparable in the first place)
|
||||
*/
|
||||
int compare(Object firstObject, Object secondObject) throws EvaluationException;
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -35,22 +35,23 @@ public interface TypeConverter {
|
|||
* to the desired target type.
|
||||
* @param sourceType a type descriptor that describes the source type
|
||||
* @param targetType a type descriptor that describes the requested result type
|
||||
* @return true if that conversion can be performed
|
||||
* @return {@code true} if that conversion can be performed
|
||||
*/
|
||||
boolean canConvert(TypeDescriptor sourceType, TypeDescriptor targetType);
|
||||
|
||||
/**
|
||||
* Convert (may coerce) a value from one type to another, for example from a boolean
|
||||
* to a string. The typeDescriptor parameter enables support for typed collections -
|
||||
* if the caller really wishes they can have a List<Integer> for example, rather
|
||||
* than simply a List.
|
||||
* Convert (or coerce) a value from one type to another, for example from a
|
||||
* {@code boolean} to a {@code String}.
|
||||
* <p>The {@link TypeDescriptor} parameters enable support for typed collections:
|
||||
* A caller may prefer a {@code List<Integer>}, for example, rather than
|
||||
* simply any {@code List}.
|
||||
* @param value the value to be converted
|
||||
* @param sourceType a type descriptor that supplies extra information about the
|
||||
* source object
|
||||
* @param targetType a type descriptor that supplies extra information about the
|
||||
* requested result type
|
||||
* @return the converted value
|
||||
* @throws EvaluationException if conversion is not possible
|
||||
* @throws EvaluationException if conversion failed or is not possible to begin with
|
||||
*/
|
||||
Object convertValue(Object value, TypeDescriptor sourceType, TypeDescriptor targetType);
|
||||
|
||||
|
|
|
|||
|
|
@ -17,11 +17,12 @@
|
|||
package org.springframework.expression;
|
||||
|
||||
/**
|
||||
* Implementors of this interface are expected to be able to locate types. They may use
|
||||
* custom classloaders or the and deal with common package prefixes (java.lang, etc)
|
||||
* however they wish. See
|
||||
* {@link org.springframework.expression.spel.support.StandardTypeLocator} for an example
|
||||
* implementation.
|
||||
* Implementers of this interface are expected to be able to locate types.
|
||||
* They may use a custom {@link ClassLoader} and/or deal with common
|
||||
* package prefixes (e.g. {@code java.lang}) however they wish.
|
||||
*
|
||||
* <p>See {@link org.springframework.expression.spel.support.StandardTypeLocator}
|
||||
* for an example implementation.
|
||||
*
|
||||
* @author Andy Clement
|
||||
* @since 3.0
|
||||
|
|
@ -29,12 +30,12 @@ package org.springframework.expression;
|
|||
public interface TypeLocator {
|
||||
|
||||
/**
|
||||
* Find a type by name. The name may or may not be fully qualified (eg. String or
|
||||
* java.lang.String)
|
||||
* @param typename the type to be located
|
||||
* @return the class object representing that type
|
||||
* @throws EvaluationException if there is a problem finding it
|
||||
* Find a type by name. The name may or may not be fully qualified
|
||||
* (e.g. {@code String} or {@code java.lang.String}).
|
||||
* @param typeName the type to be located
|
||||
* @return the {@code Class} object representing that type
|
||||
* @throws EvaluationException if there is a problem finding the type
|
||||
*/
|
||||
Class<?> findType(String typename) throws EvaluationException;
|
||||
Class<?> findType(String typeName) throws EvaluationException;
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -18,7 +18,6 @@ package org.springframework.expression.spel.support;
|
|||
|
||||
import org.springframework.core.convert.ConversionException;
|
||||
import org.springframework.core.convert.ConversionService;
|
||||
import org.springframework.core.convert.ConverterNotFoundException;
|
||||
import org.springframework.core.convert.TypeDescriptor;
|
||||
import org.springframework.core.convert.support.DefaultConversionService;
|
||||
import org.springframework.expression.TypeConverter;
|
||||
|
|
@ -27,8 +26,8 @@ import org.springframework.expression.spel.SpelMessage;
|
|||
import org.springframework.util.Assert;
|
||||
|
||||
/**
|
||||
* Default implementation of the {@link TypeConverter} interface, delegating to a core
|
||||
* Spring {@link ConversionService}.
|
||||
* Default implementation of the {@link TypeConverter} interface,
|
||||
* delegating to a core Spring {@link ConversionService}.
|
||||
*
|
||||
* @author Juergen Hoeller
|
||||
* @author Andy Clement
|
||||
|
|
@ -42,6 +41,9 @@ public class StandardTypeConverter implements TypeConverter {
|
|||
private final ConversionService conversionService;
|
||||
|
||||
|
||||
/**
|
||||
* Create a StandardTypeConverter for the default ConversionService.
|
||||
*/
|
||||
public StandardTypeConverter() {
|
||||
synchronized (this) {
|
||||
if (defaultConversionService == null) {
|
||||
|
|
@ -51,6 +53,10 @@ public class StandardTypeConverter implements TypeConverter {
|
|||
this.conversionService = defaultConversionService;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a StandardTypeConverter for the given ConversionService.
|
||||
* @param conversionService the ConversionService to delegate to
|
||||
*/
|
||||
public StandardTypeConverter(ConversionService conversionService) {
|
||||
Assert.notNull(conversionService, "ConversionService must not be null");
|
||||
this.conversionService = conversionService;
|
||||
|
|
@ -67,10 +73,6 @@ public class StandardTypeConverter implements TypeConverter {
|
|||
try {
|
||||
return this.conversionService.convert(value, sourceType, targetType);
|
||||
}
|
||||
catch (ConverterNotFoundException ex) {
|
||||
throw new SpelEvaluationException(
|
||||
ex, SpelMessage.TYPE_CONVERSION_ERROR, sourceType.toString(), targetType.toString());
|
||||
}
|
||||
catch (ConversionException ex) {
|
||||
throw new SpelEvaluationException(
|
||||
ex, SpelMessage.TYPE_CONVERSION_ERROR, sourceType.toString(), targetType.toString());
|
||||
|
|
|
|||
|
|
@ -16,8 +16,8 @@
|
|||
|
||||
package org.springframework.expression.spel.support;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
|
||||
import org.springframework.expression.EvaluationException;
|
||||
|
|
@ -27,9 +27,9 @@ import org.springframework.expression.spel.SpelMessage;
|
|||
import org.springframework.util.ClassUtils;
|
||||
|
||||
/**
|
||||
* A default implementation of a TypeLocator that uses the context classloader (or any
|
||||
* classloader set upon it). It supports 'well known' packages so if a type cannot be
|
||||
* found it will try the registered imports to locate it.
|
||||
* A simple implementation of {@link TypeLocator} that uses the context ClassLoader
|
||||
* (or any ClassLoader set upon it). It supports 'well-known' packages: So if a
|
||||
* type cannot be found, it will try the registered imports to locate it.
|
||||
*
|
||||
* @author Andy Clement
|
||||
* @author Juergen Hoeller
|
||||
|
|
@ -37,50 +37,30 @@ import org.springframework.util.ClassUtils;
|
|||
*/
|
||||
public class StandardTypeLocator implements TypeLocator {
|
||||
|
||||
private final ClassLoader loader;
|
||||
private final ClassLoader classLoader;
|
||||
|
||||
private final List<String> knownPackagePrefixes = new ArrayList<String>();
|
||||
private final List<String> knownPackagePrefixes = new LinkedList<String>();
|
||||
|
||||
|
||||
/**
|
||||
* Create a StandardTypeLocator for the default ClassLoader
|
||||
* (typically, the thread context ClassLoader).
|
||||
*/
|
||||
public StandardTypeLocator() {
|
||||
this(ClassUtils.getDefaultClassLoader());
|
||||
}
|
||||
|
||||
public StandardTypeLocator(ClassLoader loader) {
|
||||
this.loader = loader;
|
||||
// Similar to when writing Java, it only knows about java.lang by default
|
||||
/**
|
||||
* Create a StandardTypeLocator for the given ClassLoader.
|
||||
* @param classLoader the ClassLoader to delegate to
|
||||
*/
|
||||
public StandardTypeLocator(ClassLoader classLoader) {
|
||||
this.classLoader = classLoader;
|
||||
// Similar to when writing regular Java code, it only knows about java.lang by default
|
||||
registerImport("java.lang");
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Find a (possibly unqualified) type reference - first using the typename as is, then trying any registered
|
||||
* prefixes if the typename cannot be found.
|
||||
* @param typename the type to locate
|
||||
* @return the class object for the type
|
||||
* @throws EvaluationException if the type cannot be found
|
||||
*/
|
||||
@Override
|
||||
public Class<?> findType(String typename) throws EvaluationException {
|
||||
String nameToLookup = typename;
|
||||
try {
|
||||
return this.loader.loadClass(nameToLookup);
|
||||
}
|
||||
catch (ClassNotFoundException ey) {
|
||||
// try any registered prefixes before giving up
|
||||
}
|
||||
for (String prefix : this.knownPackagePrefixes) {
|
||||
try {
|
||||
nameToLookup = new StringBuilder().append(prefix).append(".").append(typename).toString();
|
||||
return this.loader.loadClass(nameToLookup);
|
||||
}
|
||||
catch (ClassNotFoundException ex) {
|
||||
// might be a different prefix
|
||||
}
|
||||
}
|
||||
throw new SpelEvaluationException(SpelMessage.TYPE_NOT_FOUND, typename);
|
||||
}
|
||||
|
||||
/**
|
||||
* Register a new import prefix that will be used when searching for unqualified types.
|
||||
* Expected format is something like "java.lang".
|
||||
|
|
@ -90,16 +70,49 @@ public class StandardTypeLocator implements TypeLocator {
|
|||
this.knownPackagePrefixes.add(prefix);
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove that specified prefix from this locator's list of imports.
|
||||
* @param prefix the prefix to remove
|
||||
*/
|
||||
public void removeImport(String prefix) {
|
||||
this.knownPackagePrefixes.remove(prefix);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a list of all the import prefixes registered with this StandardTypeLocator.
|
||||
* @return list of registered import prefixes
|
||||
* @return a list of registered import prefixes
|
||||
*/
|
||||
public List<String> getImportPrefixes() {
|
||||
return Collections.unmodifiableList(this.knownPackagePrefixes);
|
||||
}
|
||||
|
||||
public void removeImport(String prefix) {
|
||||
this.knownPackagePrefixes.remove(prefix);
|
||||
|
||||
/**
|
||||
* Find a (possibly unqualified) type reference - first using the type name as-is,
|
||||
* then trying any registered prefixes if the type name cannot be found.
|
||||
* @param typeName the type to locate
|
||||
* @return the class object for the type
|
||||
* @throws EvaluationException if the type cannot be found
|
||||
*/
|
||||
@Override
|
||||
public Class<?> findType(String typeName) throws EvaluationException {
|
||||
String nameToLookup = typeName;
|
||||
try {
|
||||
return this.classLoader.loadClass(nameToLookup);
|
||||
}
|
||||
catch (ClassNotFoundException ey) {
|
||||
// try any registered prefixes before giving up
|
||||
}
|
||||
for (String prefix : this.knownPackagePrefixes) {
|
||||
try {
|
||||
nameToLookup = prefix + "." + typeName;
|
||||
return this.classLoader.loadClass(nameToLookup);
|
||||
}
|
||||
catch (ClassNotFoundException ex) {
|
||||
// might be a different prefix
|
||||
}
|
||||
}
|
||||
throw new SpelEvaluationException(SpelMessage.TYPE_NOT_FOUND, typeName);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -133,14 +133,14 @@ public class SpelReproTests extends ExpressionTestCase {
|
|||
static class MyTypeLocator extends StandardTypeLocator {
|
||||
|
||||
@Override
|
||||
public Class<?> findType(String typename) throws EvaluationException {
|
||||
if (typename.equals("Spr5899Class")) {
|
||||
public Class<?> findType(String typeName) throws EvaluationException {
|
||||
if (typeName.equals("Spr5899Class")) {
|
||||
return Spr5899Class.class;
|
||||
}
|
||||
if (typename.equals("Outer")) {
|
||||
if (typeName.equals("Outer")) {
|
||||
return Outer.class;
|
||||
}
|
||||
return super.findType(typename);
|
||||
return super.findType(typeName);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -25,9 +25,13 @@ import java.util.List;
|
|||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.Callable;
|
||||
|
||||
import javax.websocket.*;
|
||||
import javax.websocket.ClientEndpointConfig;
|
||||
import javax.websocket.ClientEndpointConfig.Configurator;
|
||||
import javax.websocket.ContainerProvider;
|
||||
import javax.websocket.Endpoint;
|
||||
import javax.websocket.Extension;
|
||||
import javax.websocket.HandshakeResponse;
|
||||
import javax.websocket.WebSocketContainer;
|
||||
|
||||
import org.springframework.core.task.AsyncListenableTaskExecutor;
|
||||
import org.springframework.core.task.SimpleAsyncTaskExecutor;
|
||||
|
|
@ -35,17 +39,17 @@ import org.springframework.core.task.TaskExecutor;
|
|||
import org.springframework.http.HttpHeaders;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.util.concurrent.ListenableFuture;
|
||||
import org.springframework.web.socket.WebSocketExtension;
|
||||
import org.springframework.web.socket.WebSocketHandler;
|
||||
import org.springframework.web.socket.WebSocketSession;
|
||||
import org.springframework.web.socket.adapter.standard.StandardWebSocketHandlerAdapter;
|
||||
import org.springframework.web.socket.adapter.standard.StandardWebSocketSession;
|
||||
import org.springframework.web.socket.adapter.standard.WebSocketToStandardExtensionAdapter;
|
||||
import org.springframework.web.socket.client.AbstractWebSocketClient;
|
||||
import org.springframework.web.socket.WebSocketExtension;
|
||||
|
||||
/**
|
||||
* Initiates WebSocket requests to a WebSocket server programatically through the standard
|
||||
* Java WebSocket API.
|
||||
* Initiates WebSocket requests to a WebSocket server programmatically
|
||||
* through the standard Java WebSocket API.
|
||||
*
|
||||
* @author Rossen Stoyanchev
|
||||
* @since 4.0
|
||||
|
|
@ -54,26 +58,25 @@ public class StandardWebSocketClient extends AbstractWebSocketClient {
|
|||
|
||||
private final WebSocketContainer webSocketContainer;
|
||||
|
||||
private AsyncListenableTaskExecutor taskExecutor =
|
||||
new SimpleAsyncTaskExecutor("WebSocketClient-");
|
||||
private AsyncListenableTaskExecutor taskExecutor = new SimpleAsyncTaskExecutor("WebSocketClient-");
|
||||
|
||||
|
||||
/**
|
||||
* Default constructor that calls {@code ContainerProvider.getWebSocketContainer()} to
|
||||
* obtain a {@link WebSocketContainer} instance.
|
||||
* Default constructor that calls {@code ContainerProvider.getWebSocketContainer()}
|
||||
* to obtain a {@link WebSocketContainer} instance.
|
||||
*/
|
||||
public StandardWebSocketClient() {
|
||||
this.webSocketContainer = ContainerProvider.getWebSocketContainer();
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor that accepts a pre-configured {@link WebSocketContainer} instance. If
|
||||
* using XML configuration see {@link WebSocketContainerFactoryBean}. In Java
|
||||
* Constructor that accepts a pre-configured {@link WebSocketContainer} instance.
|
||||
* If using XML configuration see {@link WebSocketContainerFactoryBean}. In Java
|
||||
* configuration use {@code ContainerProvider.getWebSocketContainer()} to obtain
|
||||
* a container instance.
|
||||
*/
|
||||
public StandardWebSocketClient(WebSocketContainer webSocketContainer) {
|
||||
Assert.notNull(webSocketContainer, "webSocketContainer must not be null");
|
||||
Assert.notNull(webSocketContainer, "WebSocketContainer must not be null");
|
||||
this.webSocketContainer = webSocketContainer;
|
||||
}
|
||||
|
||||
|
|
@ -94,6 +97,7 @@ public class StandardWebSocketClient extends AbstractWebSocketClient {
|
|||
return this.taskExecutor;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
protected ListenableFuture<WebSocketSession> doHandshakeInternal(WebSocketHandler webSocketHandler,
|
||||
HttpHeaders headers, final URI uri, List<String> protocols,
|
||||
|
|
@ -133,7 +137,7 @@ public class StandardWebSocketClient extends AbstractWebSocketClient {
|
|||
try {
|
||||
return InetAddress.getLocalHost();
|
||||
}
|
||||
catch (UnknownHostException e) {
|
||||
catch (UnknownHostException ex) {
|
||||
return InetAddress.getLoopbackAddress();
|
||||
}
|
||||
}
|
||||
|
|
@ -141,7 +145,7 @@ public class StandardWebSocketClient extends AbstractWebSocketClient {
|
|||
private int getPort(URI uri) {
|
||||
if (uri.getPort() == -1) {
|
||||
String scheme = uri.getScheme().toLowerCase(Locale.ENGLISH);
|
||||
return "wss".equals(scheme) ? 443 : 80;
|
||||
return ("wss".equals(scheme) ? 443 : 80);
|
||||
}
|
||||
return uri.getPort();
|
||||
}
|
||||
|
|
@ -151,7 +155,6 @@ public class StandardWebSocketClient extends AbstractWebSocketClient {
|
|||
|
||||
private final HttpHeaders headers;
|
||||
|
||||
|
||||
public StandardWebSocketClientConfigurator(HttpHeaders headers) {
|
||||
this.headers = headers;
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue