提交 6051ea8a 编写于 作者: J Juergen Hoeller

Polishing

上级 838855b1
......@@ -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)
* @return {@code true} if the comparator can compare these objects
*/
int compare(Object firstObject, Object secondObject) throws EvaluationException;
boolean canCompare(Object firstObject, Object secondObject);
/**
* Return true if the comparator can compare these two objects
* Compare two given objects.
* @param firstObject the first object
* @param secondObject the second object
* @return true if the comparator can compare these objects
* @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)
*/
boolean canCompare(Object firstObject, Object secondObject);
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&lt;Integer&gt; 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&lt;Integer&gt;}, 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,69 +37,82 @@ 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
* Register a new import prefix that will be used when searching for unqualified types.
* Expected format is something like "java.lang".
* @param prefix the prefix to register
*/
public void registerImport(String prefix) {
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 a list of registered import prefixes
*/
public List<String> getImportPrefixes() {
return Collections.unmodifiableList(this.knownPackagePrefixes);
}
/**
* 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;
public Class<?> findType(String typeName) throws EvaluationException {
String nameToLookup = typeName;
try {
return this.loader.loadClass(nameToLookup);
return this.classLoader.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);
nameToLookup = prefix + "." + typeName;
return this.classLoader.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".
* @param prefix the prefix to register
*/
public void registerImport(String prefix) {
this.knownPackagePrefixes.add(prefix);
}
/**
* Return a list of all the import prefixes registered with this StandardTypeLocator.
* @return list of registered import prefixes
*/
public List<String> getImportPrefixes() {
return Collections.unmodifiableList(this.knownPackagePrefixes);
}
public void removeImport(String prefix) {
this.knownPackagePrefixes.remove(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;
}
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册