diff --git a/spring-expression/src/main/java/org/springframework/expression/TypeComparator.java b/spring-expression/src/main/java/org/springframework/expression/TypeComparator.java index c939fcab11c..d12122dbbc8 100644 --- a/spring-expression/src/main/java/org/springframework/expression/TypeComparator.java +++ b/spring-expression/src/main/java/org/springframework/expression/TypeComparator.java @@ -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; + } diff --git a/spring-expression/src/main/java/org/springframework/expression/TypeConverter.java b/spring-expression/src/main/java/org/springframework/expression/TypeConverter.java index 2fad0f98a5c..ee78104dcad 100644 --- a/spring-expression/src/main/java/org/springframework/expression/TypeConverter.java +++ b/spring-expression/src/main/java/org/springframework/expression/TypeConverter.java @@ -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}. + *

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); diff --git a/spring-expression/src/main/java/org/springframework/expression/TypeLocator.java b/spring-expression/src/main/java/org/springframework/expression/TypeLocator.java index 7fade5cb7b1..e9696268953 100644 --- a/spring-expression/src/main/java/org/springframework/expression/TypeLocator.java +++ b/spring-expression/src/main/java/org/springframework/expression/TypeLocator.java @@ -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. + * + *

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; } diff --git a/spring-expression/src/main/java/org/springframework/expression/spel/support/StandardTypeConverter.java b/spring-expression/src/main/java/org/springframework/expression/spel/support/StandardTypeConverter.java index 1754e1eb465..690a7e57267 100644 --- a/spring-expression/src/main/java/org/springframework/expression/spel/support/StandardTypeConverter.java +++ b/spring-expression/src/main/java/org/springframework/expression/spel/support/StandardTypeConverter.java @@ -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()); diff --git a/spring-expression/src/main/java/org/springframework/expression/spel/support/StandardTypeLocator.java b/spring-expression/src/main/java/org/springframework/expression/spel/support/StandardTypeLocator.java index 8fea968184f..14fa767c1e9 100644 --- a/spring-expression/src/main/java/org/springframework/expression/spel/support/StandardTypeLocator.java +++ b/spring-expression/src/main/java/org/springframework/expression/spel/support/StandardTypeLocator.java @@ -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 knownPackagePrefixes = new ArrayList(); + private final List knownPackagePrefixes = new LinkedList(); + /** + * 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 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); } } diff --git a/spring-expression/src/test/java/org/springframework/expression/spel/SpelReproTests.java b/spring-expression/src/test/java/org/springframework/expression/spel/SpelReproTests.java index 7abc5dd52af..6a210260cfc 100644 --- a/spring-expression/src/test/java/org/springframework/expression/spel/SpelReproTests.java +++ b/spring-expression/src/test/java/org/springframework/expression/spel/SpelReproTests.java @@ -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); } } diff --git a/spring-websocket/src/main/java/org/springframework/web/socket/client/standard/StandardWebSocketClient.java b/spring-websocket/src/main/java/org/springframework/web/socket/client/standard/StandardWebSocketClient.java index 6a1b8a37028..0eeabbf03a9 100644 --- a/spring-websocket/src/main/java/org/springframework/web/socket/client/standard/StandardWebSocketClient.java +++ b/spring-websocket/src/main/java/org/springframework/web/socket/client/standard/StandardWebSocketClient.java @@ -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 doHandshakeInternal(WebSocketHandler webSocketHandler, HttpHeaders headers, final URI uri, List 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; }