From 6045914057658eec8448b5c3cc03f4b9f82ccea8 Mon Sep 17 00:00:00 2001 From: Juergen Hoeller Date: Fri, 3 Jan 2014 23:02:51 +0100 Subject: [PATCH] Polishing --- .../concurrent/ThreadPoolTaskScheduler.java | 12 +++-- .../core/convert/TypeDescriptor.java | 2 +- .../core/task/AsyncTaskExecutor.java | 4 +- .../task/support/TaskExecutorAdapter.java | 12 ++--- .../springframework/util/AntPathMatcher.java | 51 ++++++++++++------- .../AnnotationDrivenBeanDefinitionParser.java | 33 ++++++------ 6 files changed, 68 insertions(+), 46 deletions(-) diff --git a/spring-context/src/main/java/org/springframework/scheduling/concurrent/ThreadPoolTaskScheduler.java b/spring-context/src/main/java/org/springframework/scheduling/concurrent/ThreadPoolTaskScheduler.java index e8961e05e3..2dea1cfc0e 100644 --- a/spring-context/src/main/java/org/springframework/scheduling/concurrent/ThreadPoolTaskScheduler.java +++ b/spring-context/src/main/java/org/springframework/scheduling/concurrent/ThreadPoolTaskScheduler.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2012 the original author or authors. + * Copyright 2002-2013 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. @@ -140,10 +140,11 @@ public class ThreadPoolTaskScheduler extends ExecutorConfigurationSupport public Future submit(Callable task) { ExecutorService executor = getScheduledExecutor(); try { + Callable taskToUse = task; if (this.errorHandler != null) { - task = new DelegatingErrorHandlingCallable(task, this.errorHandler); + taskToUse = new DelegatingErrorHandlingCallable(task, this.errorHandler); } - return executor.submit(task); + return executor.submit(taskToUse); } catch (RejectedExecutionException ex) { throw new TaskRejectedException("Executor [" + executor + "] did not accept task: " + task, ex); @@ -222,6 +223,7 @@ public class ThreadPoolTaskScheduler extends ExecutorConfigurationSupport } } + private Runnable errorHandlingTask(Runnable task, boolean isRepeatingTask) { return TaskUtils.decorateTaskWithErrorHandler(task, this.errorHandler, isRepeatingTask); } @@ -233,14 +235,14 @@ public class ThreadPoolTaskScheduler extends ExecutorConfigurationSupport private final ErrorHandler errorHandler; - DelegatingErrorHandlingCallable(Callable delegate, ErrorHandler errorHandler) { + public DelegatingErrorHandlingCallable(Callable delegate, ErrorHandler errorHandler) { this.delegate = delegate; this.errorHandler = errorHandler; } public V call() throws Exception { try { - return delegate.call(); + return this.delegate.call(); } catch (Throwable t) { this.errorHandler.handleError(t); diff --git a/spring-core/src/main/java/org/springframework/core/convert/TypeDescriptor.java b/spring-core/src/main/java/org/springframework/core/convert/TypeDescriptor.java index 29fb785479..b5a3617dd8 100644 --- a/spring-core/src/main/java/org/springframework/core/convert/TypeDescriptor.java +++ b/spring-core/src/main/java/org/springframework/core/convert/TypeDescriptor.java @@ -621,7 +621,7 @@ public class TypeDescriptor implements Serializable { } private String wildcard(TypeDescriptor typeDescriptor) { - return typeDescriptor != null ? typeDescriptor.toString() : "?"; + return (typeDescriptor != null ? typeDescriptor.toString() : "?"); } diff --git a/spring-core/src/main/java/org/springframework/core/task/AsyncTaskExecutor.java b/spring-core/src/main/java/org/springframework/core/task/AsyncTaskExecutor.java index 0a68e74615..f650e1d597 100644 --- a/spring-core/src/main/java/org/springframework/core/task/AsyncTaskExecutor.java +++ b/spring-core/src/main/java/org/springframework/core/task/AsyncTaskExecutor.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2012 the original author or authors. + * Copyright 2002-2013 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. @@ -67,6 +67,7 @@ public interface AsyncTaskExecutor extends TaskExecutor { * @param task the {@code Runnable} to execute (never {@code null}) * @return a Future representing pending completion of the task * @throws TaskRejectedException if the given task was not accepted + * @since 3.0 */ Future submit(Runnable task); @@ -76,6 +77,7 @@ public interface AsyncTaskExecutor extends TaskExecutor { * @param task the {@code Callable} to execute (never {@code null}) * @return a Future representing pending completion of the task * @throws TaskRejectedException if the given task was not accepted + * @since 3.0 */ Future submit(Callable task); diff --git a/spring-core/src/main/java/org/springframework/core/task/support/TaskExecutorAdapter.java b/spring-core/src/main/java/org/springframework/core/task/support/TaskExecutorAdapter.java index bd2df283d7..f980c4d433 100644 --- a/spring-core/src/main/java/org/springframework/core/task/support/TaskExecutorAdapter.java +++ b/spring-core/src/main/java/org/springframework/core/task/support/TaskExecutorAdapter.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2012 the original author or authors. + * Copyright 2002-2013 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. @@ -28,7 +28,7 @@ import org.springframework.core.task.TaskRejectedException; import org.springframework.util.Assert; /** - * Adapter that takes a JDK 1.5 {@code java.util.concurrent.Executor} and + * Adapter that takes a JDK {@code java.util.concurrent.Executor} and * exposes a Spring {@link org.springframework.core.task.TaskExecutor} for it. * Also detects an extended {@code java.util.concurrent.ExecutorService}, adapting * the {@link org.springframework.core.task.AsyncTaskExecutor} interface accordingly. @@ -41,13 +41,13 @@ import org.springframework.util.Assert; */ public class TaskExecutorAdapter implements AsyncTaskExecutor { - private Executor concurrentExecutor; + private final Executor concurrentExecutor; /** * Create a new TaskExecutorAdapter, - * using the given JDK 1.5 concurrent executor. - * @param concurrentExecutor the JDK 1.5 concurrent executor to delegate to + * using the given JDK concurrent executor. + * @param concurrentExecutor the JDK concurrent executor to delegate to */ public TaskExecutorAdapter(Executor concurrentExecutor) { Assert.notNull(concurrentExecutor, "Executor must not be null"); @@ -56,7 +56,7 @@ public class TaskExecutorAdapter implements AsyncTaskExecutor { /** - * Delegates to the specified JDK 1.5 concurrent executor. + * Delegates to the specified JDK concurrent executor. * @see java.util.concurrent.Executor#execute(Runnable) */ public void execute(Runnable task) { diff --git a/spring-core/src/main/java/org/springframework/util/AntPathMatcher.java b/spring-core/src/main/java/org/springframework/util/AntPathMatcher.java index e7fefa175d..a4f74a4b0d 100644 --- a/spring-core/src/main/java/org/springframework/util/AntPathMatcher.java +++ b/spring-core/src/main/java/org/springframework/util/AntPathMatcher.java @@ -50,29 +50,37 @@ import java.util.regex.Pattern; */ public class AntPathMatcher implements PathMatcher { - private static final Pattern VARIABLE_PATTERN = Pattern.compile("\\{[^/]+?\\}"); - /** Default path separator: "/" */ public static final String DEFAULT_PATH_SEPARATOR = "/"; + private static final Pattern VARIABLE_PATTERN = Pattern.compile("\\{[^/]+?\\}"); + + private String pathSeparator = DEFAULT_PATH_SEPARATOR; + private boolean trimTokens = true; + private final Map stringMatcherCache = new ConcurrentHashMap(256); - private boolean trimTokens = true; - - /** Set the path separator to use for pattern parsing. Default is "/", as in Ant. */ + /** + * Set the path separator to use for pattern parsing. + * Default is "/", as in Ant. + */ public void setPathSeparator(String pathSeparator) { this.pathSeparator = (pathSeparator != null ? pathSeparator : DEFAULT_PATH_SEPARATOR); } - /** Whether to trim tokenized paths and patterns. */ + /** + * Specify whether to trim tokenized paths and patterns. + * Default is {@code true}. + */ public void setTrimTokens(boolean trimTokens) { - this.trimTokens = trimTokens; + this.trimTokens = trimTokens; } + public boolean isPattern(String path) { return (path.indexOf('*') != -1 || path.indexOf('?') != -1); } @@ -94,15 +102,13 @@ public class AntPathMatcher implements PathMatcher { * as far as the given base path goes is sufficient) * @return {@code true} if the supplied {@code path} matched, {@code false} if it didn't */ - protected boolean doMatch(String pattern, String path, boolean fullMatch, - Map uriTemplateVariables) { - + protected boolean doMatch(String pattern, String path, boolean fullMatch, Map uriTemplateVariables) { if (path.startsWith(this.pathSeparator) != pattern.startsWith(this.pathSeparator)) { return false; } - String[] pattDirs = StringUtils.tokenizeToStringArray(pattern, this.pathSeparator, this.trimTokens, true); - String[] pathDirs = StringUtils.tokenizeToStringArray(path, this.pathSeparator, this.trimTokens, true); + String[] pattDirs = tokenizePath(pattern); + String[] pathDirs = tokenizePath(path); int pattIdxStart = 0; int pattIdxEnd = pattDirs.length - 1; @@ -111,11 +117,11 @@ public class AntPathMatcher implements PathMatcher { // Match all elements up to the first ** while (pattIdxStart <= pattIdxEnd && pathIdxStart <= pathIdxEnd) { - String patDir = pattDirs[pattIdxStart]; - if ("**".equals(patDir)) { + String pattDir = pattDirs[pattIdxStart]; + if ("**".equals(pattDir)) { break; } - if (!matchStrings(patDir, pathDirs[pathIdxStart], uriTemplateVariables)) { + if (!matchStrings(pattDir, pathDirs[pathIdxStart], uriTemplateVariables)) { return false; } pattIdxStart++; @@ -152,11 +158,11 @@ public class AntPathMatcher implements PathMatcher { // up to last '**' while (pattIdxStart <= pattIdxEnd && pathIdxStart <= pathIdxEnd) { - String patDir = pattDirs[pattIdxEnd]; - if (patDir.equals("**")) { + String pattDir = pattDirs[pattIdxEnd]; + if (pattDir.equals("**")) { break; } - if (!matchStrings(patDir, pathDirs[pathIdxEnd], uriTemplateVariables)) { + if (!matchStrings(pattDir, pathDirs[pathIdxEnd], uriTemplateVariables)) { return false; } pattIdxEnd--; @@ -221,6 +227,15 @@ public class AntPathMatcher implements PathMatcher { return true; } + /** + * Tokenize the given path String into parts, based on this matcher's settings. + * @param path the path to tokenize + * @return the tokenized path parts + */ + protected String[] tokenizePath(String path) { + return StringUtils.tokenizeToStringArray(path, this.pathSeparator, this.trimTokens, true); + } + /** * Tests whether or not a string matches against a pattern. The pattern may contain two special characters: *
'*' means zero or more characters diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/config/AnnotationDrivenBeanDefinitionParser.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/config/AnnotationDrivenBeanDefinitionParser.java index 464c410e25..dd71819723 100644 --- a/spring-webmvc/src/main/java/org/springframework/web/servlet/config/AnnotationDrivenBeanDefinitionParser.java +++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/config/AnnotationDrivenBeanDefinitionParser.java @@ -165,7 +165,7 @@ class AnnotationDrivenBeanDefinitionParser implements BeanDefinitionParser { RuntimeBeanReference conversionService = getConversionService(element, source, parserContext); RuntimeBeanReference validator = getValidator(element, source, parserContext); - RuntimeBeanReference messageCodesResolver = getMessageCodesResolver(element, source, parserContext); + RuntimeBeanReference messageCodesResolver = getMessageCodesResolver(element); RootBeanDefinition bindingDef = new RootBeanDefinition(ConfigurableWebBindingInitializer.class); bindingDef.setSource(source); @@ -175,10 +175,10 @@ class AnnotationDrivenBeanDefinitionParser implements BeanDefinitionParser { bindingDef.getPropertyValues().add("messageCodesResolver", messageCodesResolver); ManagedList messageConverters = getMessageConverters(element, source, parserContext); - ManagedList argumentResolvers = getArgumentResolvers(element, source, parserContext); - ManagedList returnValueHandlers = getReturnValueHandlers(element, source, parserContext); - String asyncTimeout = getAsyncTimeout(element, source, parserContext); - RuntimeBeanReference asyncExecutor = getAsyncExecutor(element, source, parserContext); + ManagedList argumentResolvers = getArgumentResolvers(element, parserContext); + ManagedList returnValueHandlers = getReturnValueHandlers(element, parserContext); + String asyncTimeout = getAsyncTimeout(element); + RuntimeBeanReference asyncExecutor = getAsyncExecutor(element); ManagedList callableInterceptors = getCallableInterceptors(element, source, parserContext); ManagedList deferredResultInterceptors = getDeferredResultInterceptors(element, source, parserContext); @@ -324,7 +324,7 @@ class AnnotationDrivenBeanDefinitionParser implements BeanDefinitionParser { return props; } - private RuntimeBeanReference getMessageCodesResolver(Element element, Object source, ParserContext parserContext) { + private RuntimeBeanReference getMessageCodesResolver(Element element) { if (element.hasAttribute("message-codes-resolver")) { return new RuntimeBeanReference(element.getAttribute("message-codes-resolver")); } @@ -333,12 +333,12 @@ class AnnotationDrivenBeanDefinitionParser implements BeanDefinitionParser { } } - private String getAsyncTimeout(Element element, Object source, ParserContext parserContext) { + private String getAsyncTimeout(Element element) { Element asyncElement = DomUtils.getChildElementByTagName(element, "async-support"); return (asyncElement != null) ? asyncElement.getAttribute("default-timeout") : null; } - private RuntimeBeanReference getAsyncExecutor(Element element, Object source, ParserContext parserContext) { + private RuntimeBeanReference getAsyncExecutor(Element element) { Element asyncElement = DomUtils.getChildElementByTagName(element, "async-support"); if (asyncElement != null) { if (asyncElement.hasAttribute("task-executor")) { @@ -382,16 +382,16 @@ class AnnotationDrivenBeanDefinitionParser implements BeanDefinitionParser { return interceptors; } - private ManagedList getArgumentResolvers(Element element, Object source, ParserContext parserContext) { + private ManagedList getArgumentResolvers(Element element, ParserContext parserContext) { Element resolversElement = DomUtils.getChildElementByTagName(element, "argument-resolvers"); if (resolversElement != null) { ManagedList argumentResolvers = extractBeanSubElements(resolversElement, parserContext); - return wrapWebArgumentResolverBeanDefs(argumentResolvers); + return wrapWebArgumentResolverBeanDefs(argumentResolvers, parserContext); } return null; } - private ManagedList getReturnValueHandlers(Element element, Object source, ParserContext parserContext) { + private ManagedList getReturnValueHandlers(Element element, ParserContext parserContext) { Element handlersElement = DomUtils.getChildElementByTagName(element, "return-value-handlers"); if (handlersElement != null) { return extractBeanSubElements(handlersElement, parserContext); @@ -421,14 +421,15 @@ class AnnotationDrivenBeanDefinitionParser implements BeanDefinitionParser { messageConverters.add(createConverterDefinition(ResourceHttpMessageConverter.class, source)); messageConverters.add(createConverterDefinition(SourceHttpMessageConverter.class, source)); messageConverters.add(createConverterDefinition(AllEncompassingFormHttpMessageConverter.class, source)); + if (romePresent) { messageConverters.add(createConverterDefinition(AtomFeedHttpMessageConverter.class, source)); messageConverters.add(createConverterDefinition(RssChannelHttpMessageConverter.class, source)); } if (jaxb2Present) { - messageConverters - .add(createConverterDefinition(Jaxb2RootElementHttpMessageConverter.class, source)); + messageConverters.add(createConverterDefinition(Jaxb2RootElementHttpMessageConverter.class, source)); } + if (jackson2Present) { messageConverters.add(createConverterDefinition(MappingJackson2HttpMessageConverter.class, source)); } @@ -457,11 +458,13 @@ class AnnotationDrivenBeanDefinitionParser implements BeanDefinitionParser { return list; } - private ManagedList wrapWebArgumentResolverBeanDefs(List beanDefs) { + private ManagedList wrapWebArgumentResolverBeanDefs( + List beanDefs, ParserContext parserContext) { + ManagedList result = new ManagedList(); for (BeanDefinitionHolder beanDef : beanDefs) { String className = beanDef.getBeanDefinition().getBeanClassName(); - Class clazz = ClassUtils.resolveClassName(className, ClassUtils.getDefaultClassLoader()); + Class clazz = ClassUtils.resolveClassName(className, parserContext.getReaderContext().getBeanClassLoader()); if (WebArgumentResolver.class.isAssignableFrom(clazz)) { RootBeanDefinition adapter = new RootBeanDefinition(ServletWebArgumentResolverAdapter.class); adapter.getConstructorArgumentValues().addIndexedArgumentValue(0, beanDef);