Compare commits

..

1068 Commits

Author SHA1 Message Date
Spring Buildmaster beb9277d74 Release version 5.0.0.M2 2016-09-21 11:53:06 +00:00
Juergen Hoeller 89717e1783 Reactive setup refinements 2016-09-21 11:24:20 +02:00
Brian Clozel 578af59f0c Polish byte-range resource handling 2016-09-20 23:46:21 +02:00
Juergen Hoeller 129d7bef6e Polishing 2016-09-20 22:41:20 +02:00
Juergen Hoeller d94ce0a1b2 Avoid package dependency cycles 2016-09-20 22:41:11 +02:00
Juergen Hoeller 65e01eabf0 DispatcherHandler.toWebHandler/toHttpHandler convenience methods 2016-09-20 22:40:43 +02:00
Brian Clozel 5b33e02fb4 Add ClientHttpRequestInterceptor in WebClient
This commit adds a new chain-based, interception contract to be used
with `WebClient`. This is the HTTP client equivalent of the `WebFilter`
contract already implemented in web reactive server.

A `ClientHttpRequestInterceptor` implementation can transform the
outgoing HTTP request (method, URI or headers) before delegating it to
the next interceptor in the chain, or bypass the request processing
altogether and return a (cached) HTTP response.

Issue: SPR-14502
2016-09-20 18:15:07 +02:00
Brian Clozel c608103140 Add client HTTP request and response Mocks 2016-09-20 18:15:07 +02:00
Sebastien Deleuze f918a2b192 Rename beforeRead/Write() to resolveRead/WriteHints()
This commit also removes the ServerHttpResponse parameter, not
needed here since it is possible to override the write() method.

Issue: SPR-14557
2016-09-20 17:52:31 +02:00
Brian Clozel e3da8b5e9c Polish ResourceHttpRequestHandler, ResourceEncoder 2016-09-20 16:49:14 +02:00
Brian Clozel 3596e72050 Add range requests support in ResourceWebHandler
This commit handles range requests in `ResourceWebHandler`, using the
`ResourceHttpMessageWriter` configured within the handler.

This `WebHandler` will add a `HTTP_RANGE_REQUEST_HINT` writer hint
containing all the HTTP Range information of the request.

Issue: SPR-14664
2016-09-20 16:46:03 +02:00
Brian Clozel a7a9e36ca0 Add ResourceRegionHttpMessageWriter
This new `HttpMessageWriter` leverages the `ResourceRegionEncoder` to
write `ResourceRegion` to HTTP responses, thus supporting HTTP Range
requests.

Whenever possible, this message writer uses the zero copy support for
single range requests.

This `HttpMessageWriter` is never used directly, but is used as a
delegate by the `ResourceHttpMessageWriter`. When provided with the
`BOUNDARY_STRING_HINT`, the `ResourceRegionHttpMessageWriter`
adapts its behavior in order to write a single/multiple byte ranges.

Issue: SPR-14664
2016-09-20 16:18:45 +02:00
Brian Clozel 55d6f88dcd Add ResourceRegionEncoder
This commit adds the necessary infrastructure for the support of HTTP
Range requests. The new `ResourceRegionEncoder` can write
`ResourceRegion` objects as streams of bytes.

The `ResourceRegionEncoder` relies on an encoding hint
`BOUNDARY_STRING_HINT`. If present, the encoder infers that multiple
`ResourceRegion`s should be encoded and that the provided boundary
String should be used to separate ranges by mime boundaries.
If that hint is absent, only a single resource region is encoded.

Issue: SPR-14664
2016-09-20 16:14:22 +02:00
Sebastien Deleuze 1d46b8d7e1 Polish 2016-09-20 14:28:12 +02:00
Sebastien Deleuze 857e77eec2 Make ServerHttpMessageReader/Writer more powerful and flexible
This commit makes it possible, in addition to provide hints, to
perform additional operations with the request and the response
at ServerHttpMessageReader/Writer level.

AbstractServerHttpMessageReader/Writer now provide
convenient beforeRead/beforeWrite abstract methods for such need.

Issue: SPR-14557
2016-09-20 11:55:51 +02:00
Sebastien Deleuze 38f3d12e45 Do not provide hints for can*() methods anymore
Issue: SPR-14557
2016-09-20 11:55:51 +02:00
Arjen Poutsma b83a6daf4b Javadoc 2016-09-20 11:19:40 +02:00
Rossen Stoyanchev adc69097fa Fix startup exception related to ResourceWebHandler
Issue: SPR-14735
2016-09-19 21:15:42 -04:00
Juergen Hoeller d71f6fe366 Latest dependency updates (EclipseLink 2.6.4, Jackson 2.8.3, JavaMail 1.5.6) 2016-09-19 21:51:34 +02:00
Sebastien Deleuze 1bf828a149 Polish 2016-09-19 16:32:50 +02:00
Rossen Stoyanchev 99c7917124 Reset connection before delegating to handler
Resetting the connection first before invoking a failure callback on
the application handler ensures that any checks to isConnected will
return false.

Issue: SPR-14721
2016-09-19 09:04:23 -04:00
Stephane Nicoll d8a771356c Merge pull request #1180 from kosmaty:doc-formatting-fix
* pr/1180:
  Polish
  Documentation formatting fix
2016-09-19 14:58:15 +02:00
Stephane Nicoll ec865d27d8 Polish 2016-09-19 14:58:00 +02:00
Krzysztof Kosmatka 0ada3f2dab Documentation formatting fix
Removed unnecessary quotation marks that caused improper rendering
of in-line code.

Closes gh-1180
2016-09-19 14:52:06 +02:00
Stephane Nicoll 3e11a30c64 Merge pull request #1181 from kosmaty:validation-doc-formatting-fix
* pr/1181:
  Add missing quotation mark
2016-09-19 14:46:30 +02:00
Krzysztof Kosmatka 906827ea92 Add missing quotation mark
Closes gh-1181
2016-09-19 14:46:05 +02:00
Arjen Poutsma 753bb854aa Rename Configuration to StrategiesSupplier 2016-09-19 12:09:19 +02:00
Juergen Hoeller bf6653b837 Adapted to 4.3.3 backport
Issue: SPR-14728
2016-09-18 21:33:58 +02:00
Juergen Hoeller f532de92aa Revised checkResource implementation
Issue: SPR-14729
(cherry picked from commit ca17edd)
2016-09-18 21:33:52 +02:00
Brian Clozel 9e5435e6f2 Check template availability in ScriptTemplateView
This commit overrides the `checkResource` implementation in
`ScriptTemplateView` in order to check if the template file resource is
available and if the resolver can then proceed with rendering the
template.

Issue: SPR-14729
Cherry-picked from: 66b370e10
2016-09-17 22:30:54 +02:00
Sam Brannen b521aa879f Clean up warnings related to forthcoming removals in Tomcat 9 2016-09-17 16:16:06 +02:00
Sam Brannen 8f62b63663 Introduce 'value' alias for @Bean's 'name' attribute
In order to simplify configuration for use cases involving @Bean where
only a bean name or aliases are supplied as an attribute, this commit
introduces a new 'value' attribute that is an @AliasFor 'name' in @Bean.

Issue: SPR-14728
2016-09-17 16:16:06 +02:00
Arjen Poutsma 778ef02680 Rename BodyInsertor to BodyInserter 2016-09-17 16:07:00 +02:00
Arjen Poutsma b6035ce9ae Refactor BodyInsertor
Refactor BodyInsertor to expose insertion logic directly, rather than
exposing a writer function and supplier.
2016-09-17 11:48:53 +02:00
Arjen Poutsma 3f55706413 Rename BodyPopulator to BodyInsertor 2016-09-17 11:29:04 +02:00
Arjen Poutsma 1bf75e330c Fix tangle
Fixed package tangle between w.r.f.RequestPredicates and w.r.f.support.RequestWrapper.
2016-09-17 11:05:05 +02:00
Rossen Stoyanchev b2ccdfbc9e Polish error logging for HTTP reactive server classes 2016-09-16 16:09:44 -04:00
Violeta Georgieva 80ff5ae9c5 Improve exception handling when clients disconnect.
Issue: SPR-14538
2016-09-16 16:09:43 -04:00
Brian Clozel c4b9b92247 Polish ResponseExtractors 2016-09-16 21:39:38 +02:00
Rob Winch b58a06208f Add HttpBasic ClientWebRequestPostProcessor
Issue: SPR-14682
2016-09-16 21:29:59 +02:00
Rossen Stoyanchev 0bace1b0ae Add getContextPath to ServerHttpRequest
Issue: SPR-14726
2016-09-16 15:21:48 -04:00
Juergen Hoeller 3772398700 Explicit sun.nio.ch export for Netty's NioEventLoopGroup on JDK 9
Issue: SPR-14645
2016-09-16 18:59:14 +02:00
Juergen Hoeller b60af42e23 Polishing
(cherry picked from commit ace25d4)
2016-09-16 18:59:14 +02:00
Rossen Stoyanchev cf2112f539 Update intializer for the reactive servlet adapter
Move the AbstractServletHttpHandlerAdapterInitializer together with
the other two base classes in spring-web-reactive. Since the
interface is in the web package, this avoids a package cycle.
Also add a mention in the reference.

Issue: SPR-14713
2016-09-16 12:57:16 -04:00
Arjen Poutsma 2b57a4d618 Add WebApplicationInitializers for Web Reactive
This commit introduces three new WebApplicationInitializers for use with
Spring Web Reactive:

 - The AbstractServletHttpHandlerAdapterInitializer registers a
 ServletHttpHandlerAdapter that wraps a user-provided HttpHandler.

 - The AbstractDispatcherHandlerInitializer registers a
 ServletHttpHandlerAdapter that wraps a DispatcherHandler (or any
 WebHandler). The handler is provided with an application context.

 - The AbstractAnnotationConfigDispatcherHandlerInitializer is a
 subclass of the above, creating an
 AnnotationConfigApplicationContext based no provided @Configuration
 classes.

Issue: SPR-14713
2016-09-16 12:57:16 -04:00
Arjen Poutsma b703dbf6ab Polishing 2016-09-16 18:44:35 +02:00
Arjen Poutsma de3e07b320 Move instance methods before static methods 2016-09-16 18:44:35 +02:00
Arjen Poutsma c57beef95e Rename RoutingFunction to RouterFunction 2016-09-16 18:44:35 +02:00
Arjen Poutsma 228a01b298 Polishing 2016-09-16 18:44:34 +02:00
Arjen Poutsma 8072497ce2 Extract body extraction logic in w.r.f
This commit refactors the response body extraction logic into a separate
function: BodyExtractor. Standard populators can be found in
BodyExtractors.
2016-09-16 18:44:34 +02:00
Arjen Poutsma 5e730408fd Extract body population logic in w.r.f
This commit extracts the response body insertion logic into a separate
strategy interface: BodyPopulator. Standard populators can be found in
BodyPopulators.
2016-09-16 18:44:34 +02:00
Arjen Poutsma 91bde2e6b2 Refactor Router to RoutingFunctions
This commit refactors the Router into a RoutingFunctions class, by:

  - Renaming the class :)
  - Moving all Configuration logic into a separate, top-level
  Configuration class with mutable builder.
2016-09-16 18:44:34 +02:00
Rossen Stoyanchev aaa1281809 Remove Exception declaration in abstract Encoder 2016-09-16 12:20:15 -04:00
Sebastien Deleuze 9d8c089a21 Polish 2016-09-16 16:17:37 +02:00
Sebastien Deleuze 6cda08e94b Add Jackson @JsonView support
Issue: SPR-14693
2016-09-16 12:51:27 +02:00
Sebastien Deleuze e74c59bf30 Introduce ServerHttpMessageWriter/Reader to resolve hints
Issue: SPR-14693
2016-09-16 12:51:27 +02:00
Brian Clozel 084daa7fb5 Document media type registration for appcache files
Since appcache manifests can have various file extensions, developers
should register the (file extension, media type) mapping in their Spring
MVC / Reactive Web configuration.

This commit adds javadoc on both `AppCacheManifestTransformer` variants
to explain how to do that.

Issue: SPR-14510
2016-09-16 12:04:56 +02:00
Juergen Hoeller 3fdc11e739 Latest dependency updates (Undertow 1.4.3, EhCache 3.1.2, Caffeine 2.3.3, Rome 1.7, Woodstox 5.0.3, Jettison 1.3.8, JRuby 9.1.5.0, RxJava 2.0 RC2, RxNetty 0.5.2 RC4) 2016-09-16 10:39:26 +02:00
Juergen Hoeller 2b2cc2d1ca Rearranged field order in RootBeanDefinition
Issue: SPR-14725
2016-09-16 10:34:05 +02:00
Stephane Nicoll 2b0bf9f04a Add Qualified element on RootBeanDefinition
Improve RootBeanDefinition to specify an AnnotatedElement that holds
qualifier information. When such element is present, any qualifier that
it defines will be used to find a matching candidate.

Issue: SPR-14725
2016-09-16 09:20:31 +02:00
Juergen Hoeller f24ce76edb StringUtils.parseLocaleString accepts Java 7 variants
Issue: SPR-14718
2016-09-15 14:31:05 +02:00
Juergen Hoeller 6de4b12992 Adapted recent tests to pass on Windows 2016-09-15 14:12:49 +02:00
Juergen Hoeller 6dc1898dbb Timeout exceptions as RuntimeExceptions
Issue: SPR-14669
2016-09-15 08:54:17 +02:00
Rossen Stoyanchev 765b47246a Improve async request timeout handling
Rather than setting the status to 503 directly from the timeout
interceptor which no longer seems to work reliably with Servlet
containers like Jetty even performing an additional ERROR dispatch back
to the original URL, we know rather set the DeferredResult to an
AsyncTimeoutException, which results in a dispatch and standard
handling within Spring MVC. This should be a more reliable way of
dealing with timeouts.

Issue: SPR-14669
2016-09-14 21:34:30 -04:00
Rossen Stoyanchev 8ccfecc406 Workaround for Content-Length issue in Reactor Netty
Issue: SPR-14643
2016-09-14 17:45:27 -04:00
Rossen Stoyanchev e024aa0049 Follow up fix for PR #1168 2016-09-14 17:35:14 -04:00
Rossen Stoyanchev 3bc1121b9d Check both connection and connected flag
Issue: SPR-14703
2016-09-14 17:19:49 -04:00
Arjen Poutsma c6a61e0d85 Add Resource.readableChannel()
Added readableChannel() to Resource, which returns a
java.nio.ReadableByteChannel. The default implementation uses
Channels.newChannel() to create a channel based on what is returned from
getInputStream(). Subclasses have more effecient, file-based
implementations.

Issue: SPR-14698
2016-09-14 15:46:15 -04:00
Stephane Nicoll 06395f41cb Merge pull request #1172 from kosmaty:punctuation-formatting-fix
* pr/1172:
  Fix doc style
2016-09-14 11:08:02 +02:00
kosmaty eef41fd8ab Fix doc style
Closes gh-1172
2016-09-14 11:07:26 +02:00
Rossen Stoyanchev bc14c5ba83 Polish [CssLinkResource|AppCacheManifest]Transformer
This commit updates the two transformers to make them more
consistent with updates of their spring-web-reactive equivalents.

Issue: SPR-14521
2016-09-13 18:04:40 -04:00
Rossen Stoyanchev 33d90747a1 Asynchronous ResourceResolver + ResourceTransformer
Issue: SPR-14521
2016-09-13 18:04:40 -04:00
Juergen Hoeller f592599349 Polishing
(cherry picked from commit 54db496)
2016-09-13 23:48:41 +02:00
Juergen Hoeller 782c99dfaf PropertySourcesPropertyResolver does not log retrieved value by default
Issue: SPR-14709
(cherry picked from commit fbe7ddb)
2016-09-13 23:48:15 +02:00
Juergen Hoeller ce42ed4d44 Polishing 2016-09-13 21:58:41 +02:00
Juergen Hoeller c69e6a36f7 Revised IllegalArgumentException handling for Formatter parse calls
Issue: SPR-14661
2016-09-13 21:55:20 +02:00
Juergen Hoeller 0c2e8a6246 Consistent callbacks for TypeFilters, ImportSelectors and ImportBeanDefinitionRegistrars
Issue: SPR-14686
2016-09-13 21:49:24 +02:00
Juergen Hoeller 5405c07d26 Configuration class processing uses MetadataReaderFactory for current ResourceLoader
Issue: SPR-14684
2016-09-13 21:47:32 +02:00
Juergen Hoeller 34ab818dfa HibernateExceptionTranslator avoids JPA IllegalState/ArgumentException translation
Issue: SPR-14681
2016-09-13 21:46:02 +02:00
Juergen Hoeller 480cd2c2f0 IdentityHashMap for scheduled tasks (avoiding hashCode calls on bean instances)
Issue: SPR-14666
2016-09-13 21:44:29 +02:00
Juergen Hoeller a86f6d3676 ApplicationEventPublisher as functional interface
Issue: SPR-14699
2016-09-13 21:42:23 +02:00
Juergen Hoeller 915350d0ce Reliable last-modified timestamp tests on Windows 2016-09-13 21:41:11 +02:00
Juergen Hoeller 118d093eaf Drop defensive Joda-Time 2.x check 2016-09-13 21:37:44 +02:00
Juergen Hoeller d5c9cc62f1 Correct ISO DateTime example
Issue: SPR-14675
2016-09-13 21:36:41 +02:00
Juergen Hoeller edbc1e9212 Avoid outdated Tibco workaround in shouldCommitAfterNoMessageReceived
Issue: SPR-14697
2016-09-13 21:34:47 +02:00
Juergen Hoeller fa820bc0c9 PropertyValue stores source object in common superclass field
Issue: SPR-8337
2016-09-13 21:29:05 +02:00
Juergen Hoeller 6f491bb319 Upgrade to Tomcat 8.5.5 and Undertow 1.4.2 2016-09-13 21:27:01 +02:00
Arjen Poutsma 360ef5f5e3 Remove accidentally added ModelAndView class
Removed accidentally added ModelAndView class.
2016-09-13 20:16:41 +02:00
Sebastien Deleuze fc52ddcd97 Polish 2016-09-13 15:03:13 +02:00
Arjen Poutsma d8f4d37624 Fixed bug in reading Flux from Channel
Fixed bug where the returned Flux from DataBufferUtils.read() would be
completed prematurely if the channel was not ready to read, but did
not reach the end of the file either.
2016-09-12 19:23:15 +02:00
Arjen Poutsma 61bf6a25b7 Renamed 'and' to 'andSame' and 'andOther' to 'and'
In RoutingFunction, renamed 'and' to 'andSame', and 'andOther' to
'and' to make the commonly used method name shorter.
2016-09-12 15:41:58 +02:00
Arjen Poutsma 96ec18a9aa Merged all Response implementations into one
Merged all *Response implementations into one DefaultResponses class
2016-09-12 15:41:04 +02:00
Arjen Poutsma 35b93b2948 Add template rendering support
This commit introduces template rendering support in the web.reactive
package, through a Response.render method and a Rendering interface.
2016-09-12 15:39:49 +02:00
Sebastien Deleuze 4991b97887 Polish 2016-09-12 14:47:48 +02:00
nkjackzhang 802a4c6d02 Remove unnecessary "method" in reference manual (#1166)
From context, It seems that the first word "method" is needless,
2016-09-12 11:47:26 +02:00
Sebastien Deleuze aaba53f76a Allow to pass hints parameter in HttpMessageReader/Writer
Issue: SPR-14557
2016-09-12 11:13:27 +02:00
Sebastien Deleuze b91867cf45 Update Codec API to use Map<String, Object> for hints
Issue: SPR-14557
2016-09-12 11:08:01 +02:00
Juergen Hoeller b88ed85994 Upgrade to Hibernate Validator 5.3 CR1 (and Protobuf 3.0.2)
Issue: SPR-13965
2016-09-10 12:39:46 +02:00
Juergen Hoeller d631b4cca9 HibernateTemplate reflectively calls getNamedQuery (for runtime compatibility with Hibernate 5.0/5.1 vs 5.2)
Issue: SPR-14676
2016-09-10 12:38:04 +02:00
Juergen Hoeller 8c5660683a MappingJackson2MessageConverter adds message id and destination to type resolution exception
Issue: SPR-14672
2016-09-10 12:37:55 +02:00
Stephane Nicoll f55b4c23fc Merge pull request #1165 from nkjackzhang:patch-6
* pr/1165:
  Fix typo
2016-09-10 07:49:14 +02:00
nkjackzhang 170d8ba5c4 Fix typo
There is no attribute named `path` in `@RequestParam`, so I change it to
`name`.

Closes gh-1165
2016-09-10 07:48:25 +02:00
Brian Clozel 1881aa5b5b Change default appcache manifest file extension
This commit changes the default file extension configured with
`AppCacheManifestTranformer`. This ResourceTransformer was previously
considering `.manifest` files by default, but this has been changed in
the official spec to `appcache`, in order not to clash with Microsoft's
unregistered application/manifest type.

Issue: SPR-14687
2016-09-09 22:11:20 +02:00
Brian Clozel 4588b6c9f4 Rename ResolvedResource to HttpResource
`ResolvedResource` is a rather generic name - changing the extended
interface to something more meaningful: `HttpResource`.
For now, implementations are linked with the resource handling chain,
but this aspect has been removed from the interface documentation.

Issue: SPR-14264
2016-09-09 18:18:09 +02:00
Sam Brannen 2f2e6dffb4 Upgrade to TestNG 6.9.12 2016-09-09 18:02:47 +02:00
Arjen Poutsma e882f739bf Merge pull request #1162 from poutsma/spock_model_and_view
* spock_model_and_view:
  Fix using system default charset in view rendering
  Changed View.render method to take Map<String, ?>
2016-09-09 15:23:10 +02:00
Arjen Poutsma 5f941c1dd1 Fix using system default charset in view rendering
Prior to this commit, FreeMarkerView used the system default charset to
render. This commit switches this by defaulting to UTF-8, if no charset
is specified in the content type.

 - Add contentType parameter to AbstractView.renderInternal, used to
 determine the charset contained therein
 - Adds a defaultCharset property to AbstractView and
 ViewResolverSupport.
2016-09-09 15:22:22 +02:00
Arjen Poutsma a746c3c54e Changed View.render method to take Map<String, ?>
Changed View's render method from taking a HandlerResult to taking a
Map<String, ?>, in order to facilitate scenarios where a HandlerResult
is not available (i.e. web.reactive.function).
2016-09-09 15:22:21 +02:00
Arjen Poutsma ecf5a9f34e Added Response.build(Publisher<Void>) 2016-09-09 12:19:51 +02:00
Arjen Poutsma f4ae831f7f Polishing
- Changed Response.sse methods to allow for specific Publisher types to
 be returned in Response.
2016-09-09 10:53:45 +02:00
Sebastien Deleuze d51005fbbe Improve Encoder Javadoc 2016-09-08 13:33:36 +02:00
Arjen Poutsma 10e157a5a2 Removed unnecessary Driver file 2016-09-07 17:24:34 +02:00
Arjen Poutsma f8ac17f278 Polishing
Two changes to web.reactive.function:

 - Changed Response.stream method to allow for specific Publisher types
 to be returned in Response.

 - Router now stores HttpMessageReader|Writer retrieved from
 Configuration in the attributes as supplier, not as stream, to allow
 for multiple reads.
2016-09-07 15:29:20 +02:00
Brian Clozel d1f60e3de1 Fix default encoding in CONTRIBUTING documentation
Sources should be using UTF-8.

Issue: SPR-14674
2016-09-07 10:47:00 +02:00
Arjen Poutsma bebaee9799 Removed attributes() from Request
Removes attributes() method from Request, as it exposes a mutable map.
2016-09-07 10:10:40 +02:00
Brian Clozel ccb3c44dbc Add ResolvedResource in resource handling chain
Prior to this commit, the resource handling chain and its
`ResourceResolvers` would use specific `Resource` implementations in
order to add resource metadata to the HTTP response. For example,
`VersionedResource` and `EncodedResource` are both adding specific HTTP
response headers.

This commit aims at making this mechanism more stable and reusable,
since the previous implementation would fail in case a resolved resource
would be both a `VersionedResource` wrapping a `EncodedResource` (or the
other way arount). Only one of the specific implementations would
contribute its metadata since the code supporting that in
`ResourceHttpRequestHandler` would only check for `instanceof` tests,
whereas those implementations are acutally delegating calls to
the wrapped resource.

Now both `VersionedResource` and `EncodedResource` have been replaced by
specific implementations of `ResolvedResource`, which directly provides
those HTTP response headers as part of `getResponseHeaders()`.

This commit applies the same changes for the web reactive
implementations and its `ResourceWebHandler`.

Issue: SPR-14264
2016-09-07 09:52:33 +02:00
Artem Yakshin 42f101fb5b Update CONTRIBUTING.md 2016-09-07 09:49:19 +02:00
Artem Yakshin 5496f11f3c Update README.md 2016-09-07 09:49:19 +02:00
Stephane Nicoll 05369a2fad Merge pull request #1158 from nkjackzhang:patch-6
* pr/1158:
  Fix typo
2016-09-07 09:37:36 +02:00
nkjackzhang 00bc0b455e Fix typo
Closes gh-1158
2016-09-07 09:37:00 +02:00
Brian Clozel cc5300c4d5 Align MVC checkNotModified with reactive support
Since SPR-14522, the web reactive framework supports checkNotModified
features. This commit aligns the existing MVC infrastructure with
web reactive's behavior.

Because of the new Servlet 3.0 baseline, some constraints
aren't relevant anymore and duplicate code has been removed in
`HttpEntityMethodProcessor`.

Issue: SPR-14659
2016-09-06 18:02:48 +02:00
Brian Clozel 72e4fac28d Fix missing resources in GzipResourceResolverTests 2016-09-06 15:39:28 +02:00
Rossen Stoyanchev 4346d15cb5 Resource handling configuration
Issue: SPR-14521
2016-09-05 21:59:22 -04:00
Rossen Stoyanchev 1ae64bfbd3 Resource handling support for Spring Web Reactive
A straight-forward port of the resource handling support in
spring-webmvc to spring-web-reactive. Primarily adapting contracts and
implementations to use the reactive request and response and the
reactive ResourceHttpMessageWriter.

Issue: SPR-14521
2016-09-05 21:59:22 -04:00
Rossen Stoyanchev 108ebe0f2b Polish resource handling tests 2016-09-05 21:59:22 -04:00
Sam Brannen 3dc6f1133c Fix section ID for parallel test execution
Issue: SPR-5863
2016-09-05 19:03:26 +02:00
Sam Brannen 3e96cab0bb Document parallel test execution support in the reference manual
Issue: SPR-5863
2016-09-05 18:58:39 +02:00
Sam Brannen 6efb166c36 Document before/after test execution callbacks in reference manual
Issue: SPR-4365
2016-09-05 17:48:47 +02:00
Sam Brannen 2699504cb8 Introduce concurrency tests for Spring's JUnit 4 support
Whereas the existing TestContextConcurrencyTests verify support for
concurrency in the TestContextManager and TestContext, this commit
introduces SpringJUnit4ConcurrencyTests that verify support for
concurrent test execution in Spring's JUnit 4 support, namely in the
SpringRunner, SpringClassRule, and SpringMethodRule.

The tests executed by this new test class come from a hand-picked
collection of test classes within the test suite that is intended to
cover most categories of tests that are currently supported by the
TestContext Framework on JUnit 4.

Note, however, that the chosen test classes intentionally do not
include any classes that fall under the following categories.

 - tests that make use of Spring's @DirtiesContext support

 - tests that make use of JUnit 4's @FixMethodOrder support

 - tests that commit changes to the state of a shared in-memory database

Issue: SPR-5863
2016-09-05 17:26:25 +02:00
Sam Brannen e822e4cbe8 Improve exception msg for inactive test ApplicationContext
This commit improves the exception message thrown when a test's
ApplicationContext is no longer active by explaining that the cause
may be due to parallel test execution.

Issue: SPR-5863
2016-09-05 13:39:21 +02:00
Sam Brannen fbfad8695e Further improve thread safety for attributes in DefaultTestContext
Issue: SPR-5863
2016-09-05 13:34:25 +02:00
Sebastien Deleuze 5755b67325 Upgrade to Reactor Core 3.0.2 2016-09-03 16:19:52 +02:00
Violeta Georgieva 00617d74de Fix AbstractRequestBodyPublisher to comply with the spec
As per specification "The Subscription MUST allow the Subscriber to
call Subscription.request synchronously from within onNext or
onSubscribe". With the current implementation if Subscription.request
is called more than once when Subscriber.onSubscribe ISE will be
thrown - java.lang.IllegalStateException: DEMAND.
With this fix the implementation will not throw ISE and will allow
many invocations of Subscription.request when
Subscriber.onSubscribe.
2016-09-02 23:37:20 +02:00
Brian Clozel 01bd8b9e01 Fix null body handling in ResponseEntityResultHandler
This commit fixes `ResponseEntityResultHandler` so that it only tries to
call `writeBody` if the `ResponseEntity` is not null. In case the
response entity body is null, the response is flushed right away and the
request is signaled as handled.

Issue: SPR-14663
2016-09-02 23:01:16 +02:00
Sam Brannen a10a8e56df Support concurrent execution in TestContextManager & DefaultTestContext
Prior to this commit, executing tests concurrently in the TestContext
Framework (TCF) was unsupported and typically lead to unpredictable
results.

This commit addresses this core issue by supporting concurrent
execution in the TestContextManager and the DefaultTestContext.

Specifically, the TestContextManager now uses ThreadLocal storage for
the current TestContext, thereby ensuring that any registered
TestExecutionListeners and the TestContextManager itself operate on a
TestContext specific to the current thread.

In order to avoid repeatedly incurring the costs of the overhead of the
TCF bootstrapping process, the original TestContext built by the
TestContextBootstrapper is used as a template which is then passed to
the copy constructor of the concrete implementation of the TestContext
to create the context for the current thread. DefaultTestContext now
implements such a copy constructor, and all concrete implementations of
TestContext are encouraged to do the same.

If the TestContext built by the TestContextBootstrapper does not
provide a copy constructor, thread-safety and support for concurrency
are left completely to the implementation of the concrete TestContext.

Note, however, that this commit does not address any thread-safety or
concurrency issues in the ContextLoader SPI or its implementations.

Issue: SPR-5863
2016-09-02 20:28:02 +02:00
Sam Brannen ec7aefa858 Improve concurrency in DefaultTestContext regarding attributes
This commit inlines the basic implementation of AttributeAccessorSupport
and converts the LinkedHashMap to a ConcurrentHashMap.

In addition, attributes are now included in toString().

Issue: SPR-5863
2016-09-02 19:14:31 +02:00
Sam Brannen 5fe3bcf8f9 Polishing 2016-09-02 18:39:31 +02:00
Rossen Stoyanchev c813405ca3 Add @since tags 2016-09-02 12:19:50 -04:00
Rossen Stoyanchev a1ac51256a Add MockServerHttpRequest/Response to spring-test
Issue: SPR-14421
2016-09-02 12:15:00 -04:00
Rossen Stoyanchev 73752c295d Refactor location of MockServerHttpRequest/Response
This change puts the MockHttpServerRequest/Response under
org.springframework.mock.http.server.reactive.test which
mirrors the arrangement we have with the Servlet mock equivalents
and sets up the addition of MockHttpServerRequest/Response in
spring-test.

Issue: SPR-14421
2016-09-02 12:15:00 -04:00
Rossen Stoyanchev e17132c217 Polish MockServerHttpRequest
Issue: SPR-14421
2016-09-02 12:15:00 -04:00
Sebastien Deleuze 2cd3135c3b Upgrade to Reactor Core 3.0.1 and Reactor Netty 0.5.1 2016-09-02 15:47:11 +02:00
Rossen Stoyanchev f3dd554dbe Fix typos in docs and polish 2016-09-02 09:26:15 -04:00
Rob Winch 7788879c5a Remove stray `
Remove stray ` in import-into-idea.md
2016-09-02 08:12:06 -05:00
Rossen Stoyanchev 08b2b0ba2a Merge pull request #1150 from neetkee/patch-1 2016-09-02 09:04:13 -04:00
Rossen Stoyanchev 833a3a0566 Polish import into IntelliJ instructions 2016-09-02 09:03:34 -04:00
Artem Yakshin 409fe478bd Update import-into-idea.md
Changes, according the latest information.
2016-09-02 08:52:53 -04:00
Brian Clozel a8ba065a6e Mention AntPathMatcher regexp support
This commit documents the regexp support in `AntPathMatcher` when
matching for URL patterns. This support is also mentioned in places
where developers can register patterns for ViewControllers or resource
handlers.

Issue: SPR-14652
2016-09-02 11:35:58 +02:00
Rossen Stoyanchev 0681519255 Add checkNotModified support for view resolution
Issue: SPR-14522
2016-09-01 18:07:23 -04:00
Rossen Stoyanchev 6071e01168 Add checkNotModified support in ServerWebExchange
Issue: SPR-14522
2016-09-01 17:44:51 -04:00
Rossen Stoyanchev 638e6cc7f8 Add checkNotModified support for ResponseEntity
Issue: SPR-14522
2016-09-01 17:44:51 -04:00
Rossen Stoyanchev 9f8791ac01 Add ServerWebExchangeArgumentResolver
Issue: SPR-14658
2016-09-01 17:44:51 -04:00
Sebastien Deleuze 02bed0a34b Polishing 2016-09-01 17:15:50 +02:00
Sebastien Deleuze 06d4bb6a1a Let users control SSE stream completion
This commit avoid merging automatically the SSE stream with
Flux.never(). Since browsers automatically reconnect when
the HTTP connection is closed, it is now the user responsability
to optionally perform a concatWith(Flux.never()) on streams that
complete in order to avoid receiving the data multiple times on
client side.

The behavior with hot streams that never complete does not change.

Issue: SPR-14578
2016-09-01 17:14:24 +02:00
Sam Brannen 1af2fbfbbb Delete unused imports in spring-context-indexer 2016-09-01 16:41:49 +02:00
Sam Brannen 5202250179 Polish SpringClassRule and SpringMethodRule 2016-09-01 16:34:03 +02:00
Stephane Nicoll 749ee6065c Merge pull request #1151 from sylvainlaurent:patch-1
* pr/1151:
  Fix class literal in instanceof
2016-09-01 16:23:08 +02:00
sylvainlaurent dc3f62d576 Fix class literal in instanceof
Closes gh-1151
2016-09-01 16:22:39 +02:00
Sebastien Deleuze 76ed101a23 Update Web Reactive documentation 2016-09-01 15:42:50 +02:00
Stephane Nicoll dcade06fa0 Support for candidate components index
This commit adds a "spring-context-indexer" module that can be added to
any project in order to generate an index of candidate components defined
in the project.

`CandidateComponentsIndexer` is a standard annotation processor that
looks for source files with target annotations (typically `@Component`)
and references them in a `META-INF/spring.components` generated file.

Each entry in the index is the fully qualified name of a candidate
component and the comma-separated list of stereotypes that apply to that
candidate. A typical example of a stereotype is `@Component`. If a
project has a `com.example.FooService` annotated with `@Component` the
following `META-INF/spring.components` file is generated at compile time:

```
com.example.FooService=org.springframework.stereotype.Component
```

A new `@Indexed` annotation can be added on any annotation to instructs
the scanner to include a source file that contains that annotation. For
instance, `@Component` is meta-annotated with `@Indexed` now and adding
`@Indexed` to more annotation types will transparently improve the index
with additional information. This also works for interaces or parent
classes: adding `@Indexed` on a `Repository` base interface means that
the indexed can be queried for its implementation by using the fully
qualified name of the `Repository` interface.

The indexer also adds any class or interface that has a type-level
annotation from the `javax` package. This includes obviously JPA
(`@Entity` and related) but also CDI (`@Named`, `@ManagedBean`) and
servlet annotations (i.e. `@WebFilter`). These are meant to handle
cases where a component needs to identify candidates and use classpath
scanning currently.

If a `package-info.java` file exists, the package is registered using
a "package-info" stereotype.

Such files can later be reused by the `ApplicationContext` to avoid
using component scan. A global `CandidateComponentsIndex` can be easily
loaded from the current classpath using `CandidateComponentsIndexLoader`.

The core framework uses such infrastructure in two areas: to retrieve
the candidate `@Component`s and to build a default `PersistenceUnitInfo`.
Rather than scanning the classpath and using ASM to identify candidates,
the index is used if present.

As long as the include filters refer to an annotation that is directly
annotated with `@Indexed` or an assignable type that is directly
annotated with `@Indexed`, the index can be used since a dedicated entry
wil be present for that type. If any other unsupported include filter is
specified, we fallback on classpath scanning.

In case the index is incomplete or cannot be used, The
`spring.index.ignore` system property can be set to `true` or,
alternatively, in a "spring.properties" at the root of the classpath.

Issue: SPR-11890
2016-09-01 15:30:47 +02:00
Sebastien Deleuze 48d67a245b Add support for RxJava 2
This commit adds support for RxJava 2 Completable,
Single, Observable and Flowable types (io.reactivex package).

Issue: SPR-14628
2016-09-01 14:48:16 +02:00
Sebastien Deleuze b4641b2306 Polishing 2016-09-01 14:48:16 +02:00
Arjen Poutsma f1319f58ec Introduce new functional web API
This commit introduces a new, functional web programming model in the
org.springframework.web.reactive.function package. The key types
are:

 - Request and Response are new Java 8-DSLs for access to the HTTP
   request and response
 - HandlerFunction represents a function to handle a request to a
   response
 - RoutingFunction maps a request to a HandlerFunction
 - FilterFunction filters a routing as defined by a RoutingFunction
 - RequestPredicate is used by Router to create RoutingFunctions
 - RequestPredicates offers common RequestPredicate instances
2016-09-01 14:38:13 +02:00
Arjen Poutsma 18e491ac0a Merge pull request #1143 from poutsma/server_sent_event
* server_sent_event:
  Refactored SseEvent to ServerSentEvent
2016-09-01 13:51:25 +02:00
Arjen Poutsma 16b525f698 Refactored SseEvent to ServerSentEvent
- Renamed SseEvent to ServerSentEvent to make the name less redundant.
 - ServerSentEvent is now immutable, having a builder to create new instances.
 - Realigned the class properties to more closely match the events
   described in the spec, so that `reconnectTime` becomes `retry`, and
   `name` becomes `event`.
2016-09-01 13:47:50 +02:00
Sam Brannen d9eaa5f3ac Use Map.computeIfAbsent() in SpringClassRule
Replace manual synchronization block in SpringClassRule with Java 8's
Map.computeIfAbsent().

Issue: SPR-12421
2016-09-01 13:38:42 +02:00
Juergen Hoeller 1cf503f939 Upgrade to JSR-354 API 1.0.1 and Jackson 2.8 javadocs 2016-09-01 12:49:01 +02:00
Juergen Hoeller aff914c98e Documentation updates around configuration classes 2016-09-01 12:41:55 +02:00
Arjen Poutsma 35cf4f173b Copied getAndSub() over from Reactor
Operators.getAndSub was removed in Reactor 3.0.1, this commit copies the
implementation over to AbstractRequestBodyPublisher, which used it.
2016-09-01 11:16:01 +02:00
Sam Brannen feb02f813e Polishing 2016-08-31 20:52:39 +02:00
Sam Brannen e574820dc9 Introduce tests for @Nested tests in JUnit Jupiter
This commit introduces integration tests that verify the expected
behavior for @Nested tests in conjunction with the SpringExtension for
JUnit Jupiter, including automatic application of
TestExecutionListeners to the enclosing test instance of a @Nested
test instance.

Issue: SPR-14150
2016-08-31 20:29:08 +02:00
Sam Brannen ab7b5e5c77 Demo how to use SpringClassRule in nested test classes
Due to restrictions imposed by JUnit 4, the SpringClassRule must be
declared as a public static field, which makes it impossible to be
declared directly within a nested (i.e., inner) test class.

This commit demonstrates a work-around that makes it possible to use
the SpringClassRule and SpringMethodRule in a nested (i.e., inner) test
class when using a custom JUnit 4 runner such as the
HierarchicalContextRunner from Stefan Bechtold.

The trick is to have inner test classes extend a class that properly
declares the SpringClassRule and SpringMethodRule. The
SpringRuleConfigurer in this commit serves as an example.

Note, however, that each such nested test class must declare its own
@ContextConfiguration. Furthermore, TestExecutionListeners in the
Spring TestContext Framework are not applied to the enclosing instance
of such an inner test class, meaning that @Autowired fields in the
enclosing instance will not be injected, etc.

Issue: SPR-14150
2016-08-31 19:35:00 +02:00
Rob Winch 09f16747b5 Fix MergePlugin transitive dependencies
A little terminiology first:

* merge.from - a project that contains source that will be merged
               into merge.into
* merge.into - a project that contains source code that will have
               code from merge.from merged into it.

Previously a module that dependended on merge.into would not see
the merge.from module as a transitive dependency. This worked fine
from a Gradle build because all the code from merge.from is merged
into the merge.into jar. However, in an IDE it did not work because
the IDE does not assemble a jar.

This fix ensures that merge.from modules are automatically added
to the classpath of any module relying on the merge.into project.

Fixes SPR-14650
2016-08-31 11:38:24 -05:00
Sam Brannen 634d1c03a3 Introduce @EnabledIf support for JUnit Jupiter
This commit picks up where SPR-14614 left off by introducing a new
@EnabledIf annotation to serve as a logical companion to @DisabledIf.

In addition, this commit extracts common logic from DisabledIfCondition
into a new AbstractExpressionEvaluatingCondition base class which the
new EnabledIfCondition also extends.

An @EnabledOnMac annotation is also included in the Javadoc as well as
in the test suite to demonstrate support for custom composed annotations.

Issue: SPR-14644
2016-08-31 16:11:58 +02:00
Juergen Hoeller 1a30252fc9 ResolvableType.java.forRawClass(Class) supports isAssignableFrom(ResolvableType) as well
Issue: SPR-14648
2016-08-31 14:45:22 +02:00
Juergen Hoeller e08b1b75b6 @PathVariable supports 'required' attribute (for model attribute methods)
Issue: SPR-14646
2016-08-31 14:43:39 +02:00
Juergen Hoeller faf6e5d8fa Annotation tests should not rely on JDK-specific toString() representation
Issue: SPR-14645
2016-08-31 14:42:08 +02:00
Brian Clozel 7a88776329 Fix missing ResourceHttpRequestHandler init in registry
Issue: SPR-14577
2016-08-31 10:43:11 +02:00
Juergen Hoeller ab9fea6b8d Polishing
(cherry picked from commit 3767092)
2016-08-31 02:08:31 +02:00
Juergen Hoeller 31c5644691 ResponseStatusExceptionHandler in web.server.handler (plus related polishing) 2016-08-30 23:58:14 +02:00
Juergen Hoeller 4ef428de28 Polishing 2016-08-30 23:57:11 +02:00
Juergen Hoeller 03609c1518 Consistent comma splitting without regex overhead
Issue: SPR-14635
2016-08-30 23:56:58 +02:00
Juergen Hoeller 58fa63fdd1 ApplicationListenerMethodAdapter resolves order on construction
Issue: SPR-14642
2016-08-30 20:50:02 +02:00
Rossen Stoyanchev 391752abc2 Polish and update reactive getting started reference
This commit updates the instructions on getting started with
Spring Web Reactive and also updates constructors and setters to
streamline the getting started procedure.

Issue: SPR-14640
2016-08-30 14:36:19 -04:00
Rossen Stoyanchev 436486b8a1 Relax ServletContext check for resource handling
This is a follow-up on commit 3b95e0b relaxing the expectation that a
ServletContext is present. Instead we check defensively and fall back
on PathExtensionContentNegotiationStrategy which can use JAF.

Issue: SPR-14577
2016-08-30 13:04:58 -04:00
Artem Yakshin e7aecb44bb Update for IntelliJ Idea 2016.2.2
Update tutorial for import and build project in IntelliJ IDEA 2016.2.2. Steps are outdated and existing issues is not applicable in new versions.
2016-08-30 16:40:49 +02:00
Rossen Stoyanchev 16879a2cf0 Harden synchronization around SockJS heartbeats
Create an explicit heartbeat task with an experiration flag so that
it can be cancelled reliably vs relying on the ScheduledFutureTask
cancel method which may return true even if the task is already
running.

Issue: SPR-14356
2016-08-30 09:26:15 -04:00
Juergen Hoeller 2aab08f093 Polishing 2016-08-30 12:59:40 +02:00
Juergen Hoeller b19d3fc0e1 Upgrade to Jackson 2.8.2 and Netty 4.1.5 2016-08-30 12:58:44 +02:00
Juergen Hoeller 58ffca76c3 CommonsMultipartResolver explicitly converts FileSizeLimitExceededException
Issue: SPR-14638
2016-08-30 12:57:46 +02:00
Brian Clozel 960d335c35 Don't wrap resolver exceptions in InvocableHandlerMethod
Prior to this commit, exceptions thrown by the
`HandlerMethodArgumentResolver` would be wrapped into
`IllegalStateException`s.

This commit makes sure that a DEBUG log is written with the relevant
information and that the root cause is not wrapped into another
exception, so that the appropriate `ExceptionHandler` can be used to
deal with this error.

Issue: SPR-14618
2016-08-30 11:50:40 +02:00
Sebastien Deleuze e8530c917e Add Smile and CBOR Jackson data formats support
This commit adds Smile and CBOR Jackson HttpMessageConverters
and make it possible to create Smile and CBOR ObjectMapper via
Jackson2ObjectMapperBuilder, which now allows to specify any
custom JsonFactory.

Like with JSON and XML Jackson support, the relevant
HttpMessageConverters are automaticially configurered by
Spring MVC WebMvcConfigurationSupport if jackson-dataformat-smile
or jackson-dataformat-cbor dependencies are found in the classpath.

Issue: SPR-14435
2016-08-30 11:06:40 +02:00
Stephane Nicoll c399b4b3ad Upgrade to SonarQube plugin 2.1-rc1
This commit upgrades the SonarQube plugin so that it is compatible with
Gradle 3.

Issue: SPR-14569
2016-08-30 10:42:32 +02:00
Rossen Stoyanchev 204a50ee6c Fix compile issue 2016-08-29 21:06:35 -04:00
Rossen Stoyanchev 4d3c3056ed Polish media type change in ResourceHttpRequestHandler 2016-08-29 19:49:24 -04:00
Rossen Stoyanchev 8b4f60b8e5 Support receipt on DISCONNECT with simple broker
Issue: SPR-14568
2016-08-29 18:31:19 -04:00
Rossen Stoyanchev 3b95e0b6e0 Fix media type regression in resource handling
Issue: SPR-14577
2016-08-29 16:27:24 -04:00
Sebastien Deleuze 417a9d4559 Ensure correct array elements order in Jackson2JsonEncoder
Issue: SPR-14586
2016-08-29 16:22:25 +02:00
Sam Brannen b6220cc19d Trim expressions supplied to @DisabledIf
Prior to this commit, the DisabledIfCondition did not trim whitespace
from expressions configured via @DisabledIf. Consequently, results such
as "  true  " would evaluate to "false".

This commit fixes this problem by trimming all expressions configured
via @DisabledIf.

Issue: SPR-14614
2016-08-29 15:47:38 +02:00
Sam Brannen d6d05e8ca0 Remove trailing whitespace in Java source code 2016-08-29 15:25:10 +02:00
Sam Brannen 9d21abcd37 Introduce dedicated tests for DisabledIfCondition
This commit introduces tests for DisabledIfCondition that verify actual
condition evaluation results and exception handling; whereas, the
existing tests in DisabledIfTestCase only test the "happy paths" and
standard cases.

Issue: SPR-14614
2016-08-29 15:17:59 +02:00
Sam Brannen 54d6f250e2 Disallow empty expression in @DisabledIf
This commit ensures that a user provides a non-empty expression in
declarations of @DisabledIf.

Issue: SPR-14614
2016-08-29 13:43:38 +02:00
Juergen Hoeller 899ebd8ee2 Avoid collection lookups in StompCommand
Issue: SPR-14636
2016-08-29 11:54:21 +02:00
Juergen Hoeller 728a548199 Consistent use of JDK 7 AssertionError with root cause
Issue: SPR-13188
2016-08-29 11:53:00 +02:00
Sam Brannen 655097a343 Merge pull request #1144 from ttddyy/SPR-14614
* ttddyy-SPR-14614:
  Revise @DisabledIf support for JUnit Jupiter
  Introduce @DisabledIf annotation for JUnit 5
2016-08-28 21:16:59 +02:00
Sam Brannen 19369094ac Revise @DisabledIf support for JUnit Jupiter
- Extracted stand-alone DisabledIfCondition from the SpringExtension
  so that the condition is only evaluated when necessary.

- Simplified implementation of DisabledIfCondition.

- Overhauled and extended logging in DisabledIfCondition.

- DisabledIfCondition now throws an IllegalStateException if @DisabledIf
  is not present on the test element or if the expression does not
  evaluate to a String or Boolean.

- Each generated ConditionEvaluationResult now includes the actual
  expression in the default reason.

- @DisabledIf is now auto-configured to be evaluated by the
  DisabledIfCondition since it is now meta-annotated with
  @ExtendWith(DisabledIfCondition.class)

- Overhauled documentation for @DisabledIf and provided standard
  examples as well as an @DisabledOnMac annotation to demonstrate
  support for custom composed annotations.

Issue: SPR-14614
2016-08-28 21:12:38 +02:00
Tadaya Tsuyukubo c03f6c6d85 Introduce @DisabledIf annotation for JUnit 5
This commit introduces @DisabledIf annotation that takes SpEL as a
condition.  The condition is evaluated at run time whether to disable
JUnit 5 (Jupiter) test method/class.

Issue: SPR-14614
2016-08-28 21:12:38 +02:00
Stephane Nicoll eb193aea5f IDEA -> IntelliJ IDEA 2016-08-28 17:49:58 +02:00
Juergen Hoeller 57cb7c7e0a LiveBeansView exposes aliases as well
Issue: SPR-14632
2016-08-26 20:04:23 +02:00
Juergen Hoeller dfdfd72a3e Polishing
(cherry picked from commit 430180a)
2016-08-26 18:59:40 +02:00
Brian Clozel b84fefc430 Wrap RestTemplate extractor exceptions in RestClientExceptions
When using a `RestTemplate` instance within a Spring MVC application,
client exceptions may propagate in the MVC stack and can be wrongly
mapped by server `ExceptionHandlers`, leading to a wrong HTTP response
sent to the MVC client.

The `RestTemplate` instance uses `HttpMessageConverter` to decode
the remote service responses; and when those fail decoding an HTTP
response, they can throw an `HttpMessageNotReadableException`. That
exception then bubbles up through the `HttpMessageConverterExtractor`,
`RestTemplate` and the whole MVC stack, later mapped to HTTP 400
responses, since those exceptions can also be throws by the server stack
when the incoming requests can't be deserialized.

This commit wraps all `IOException` and `HttpMessageNotReadableException`
instances thrown by the extractor into `RestClientException`` instances.
It's now easier to consistently handle client exceptions and avoid such
edge cases.

Issue: SPR-13592
2016-08-26 17:56:00 +02:00
Rossen Stoyanchev 7fdb892042 Support target type in JsonPath assertions
This change adds support for a target type in JsonPath assertions in
Spring MVC Test.

The existing assertValue(String expression, Object expectedValue)
transparently falls back on using an alternative JsonPath API that
allows specifying the target type to coerce to.

There is also a new overloaded method
assertValue(String expression, Matcher<T> matcher, Class<T> targetType)
for use with Hamcrest matchers where the target type can be specified.

Issue: SPR-14498
2016-08-26 10:38:03 -04:00
Brian Clozel d8fc13f6fc Fix server errors for invalid If-None-Match request headers
HttpEntityMethodProcessor should not throw IllegalArgumentExceptions for
invalid If-None-Match headers.

For those cases, this commit makes sure that both
`HttpEntityMethodProcessor` and `ServletWebRequest` have a consistent
behavior and stop processing the request as conditional and leave the
handler handle it.

Issue: SPR-14559
2016-08-26 15:48:47 +02:00
Sam Brannen 5998a297ce Simplify exception handling in JsonPathExpectationsHelper 2016-08-26 14:43:40 +02:00
Juergen Hoeller 2e4a7480fc Consistent use of JDK 7 StandardCharsets over Charset.forName
Issue: SPR-14492
2016-08-26 14:16:19 +02:00
Brian Clozel 50040e6139 Revert "Consistently use annotation attributes in refdoc"
This reverts commit bbd5993945.
2016-08-26 13:57:18 +02:00
Juergen Hoeller 14046575b0 Polishing 2016-08-26 13:27:33 +02:00
Juergen Hoeller a8f7f75f64 Moved encodeHttpHeaderFieldParam method to HttpHeaders itself (including tests)
This commit also sets the test source encoding to UTF-8.

Issue: SPR-14547
2016-08-26 11:14:02 +02:00
Brian Clozel bbd5993945 Consistently use annotation attributes in refdoc 2016-08-26 09:38:19 +02:00
Brian Clozel f93cb2f539 Support ordered interceptors in RestTemplate
This commit sorts `ClientHttpRequestInterceptor`s when those are set in
`InterceptingHttpAccessor` (which `RestTemplate` extends from).

Interceptors can now be annotated with `@Order` or implements `Ordered`
to reflect their order of execution for each request.

Issue: SPR-13971
2016-08-25 17:14:09 +02:00
Arjen Poutsma ab7107c4c5 Added Host property to HttpHeaders
Added getHost/setHost to HttpHeaders, returning/taking a
InetSocketAddress.
2016-08-25 15:49:07 +02:00
Brian Clozel f2faf84f31 Add RFC5987 support for HTTP header field params
This commit adds support for HTTP header field parameters encoding, as
described in RFC5987.
Note that the default implementation still relies on US-ASCII encoding,
as the latest rfc7230 Section 3.2.4 says that:

> Newly defined header fields SHOULD limit their field values to
  US-ASCII octets

Issue: SPR-14547
2016-08-25 14:26:58 +02:00
Juergen Hoeller 41f7680e20 Polishing 2016-08-25 00:20:18 +02:00
Juergen Hoeller c4fcdb6864 DefaultListableBeanFactory does not trigger early candidate creation ahead of primary bean selection
Issue: SPR-14611
2016-08-24 22:56:47 +02:00
Juergen Hoeller 405e74b6ae GenericApplicationContext picks up ClassLoader from custom ResourceLoader
Issue: SPR-14626
2016-08-24 21:23:57 +02:00
Juergen Hoeller f3f691cc37 Revised assertions in StompHeaderAccessor
Issue: SPR-14625
2016-08-24 21:04:01 +02:00
Juergen Hoeller 56b197bce1 Avoid unnecessary String concatenation in StompSubProtocolHandler
Issue: SPR-14624
2016-08-24 20:12:01 +02:00
Juergen Hoeller bbc85ea466 Refined exception message
Issue: SPR-14609
(cherry picked from commit ab68673)
2016-08-24 15:08:12 +02:00
Juergen Hoeller 951ac5ea4f TransactionAspectSupport stores given PlatformTransactionManager instance as strong reference
Issue: SPR-14609
2016-08-24 14:31:02 +02:00
Juergen Hoeller 3d297b10e9 NamedBeanHolder enforces bean name
Issue: SPR-7549
2016-08-24 14:29:45 +02:00
Juergen Hoeller d9d84ff388 Polishing 2016-08-24 11:40:24 +02:00
Juergen Hoeller d047174c6b Unit test for empty Access-Control-Request-Headers (Chrome 52)
Includes optimized method/header resolution in CorsConfiguration.

Issue: SPR-14617
2016-08-24 11:40:18 +02:00
Brian Clozel e4575330c3 Support empty body in Jackson2JsonDecoder.decodeToMono
Prior to this commit, extracting an HTTP response with an empty body
and no Content-Type header using the WebClient would:

* trigger the use of the Jackson2JsonDecoder
* throw a NoSuchElementException because of the use of `Flux.single()`

This commit changes this behavior to `Flux.singleOrEmpty()` to avoid
throwing exceptions for empty Flux instances.

Issue: SPR-14582
2016-08-23 16:10:41 +02:00
Juergen Hoeller 93d2287894 UnsatisfiedDependencyException avoids duplicate nested exception message
Issue: SPR-14607
2016-08-23 13:21:40 +02:00
Juergen Hoeller c4fff6db1b Reintroduced MessageMethodArgumentResolver default constructor
Issue: SPR-14616
2016-08-23 13:20:02 +02:00
Erik Olsson 64bc0ca744 Add ClientOptions support in ReactorClientHttpConnector
Default ClientOptions enable SSL support.

Issue: SPR-14593
2016-08-23 11:17:12 +02:00
Brian Clozel e05a13841f Upgrade to latest reactor/reactor-netty snapshots
* reactor-core 3.0.1.BUILD-SNAPSHOT
* reactor-netty 0.6.0.BUILD-SNAPSHOT
2016-08-22 19:14:49 +02:00
Sam Brannen 9629afbcfd Restore JUnit XML reports location for TestNG tests
This commit ensures that JUnit XML reports are generated in the old
Gradle 2.x location for all tests in the spring-test module.

Issue: SPR-14569
2016-08-22 16:30:14 +02:00
Stephane Nicoll e6353f0ec7 Fix JUnit reports location
Issue: SPR-14569
2016-08-22 14:50:18 +02:00
Stephane Nicoll c64cdcc47f Restore JUnit reports location
Since the upgrade to Gradle 3, our Bamboo build is failing because it
can't find test reports "at the usual location".

This commit restores the location that Gradle 2 was using until we
upgrade to a version of Bamboo that supports it.

Issue: SPR-14569
2016-08-22 14:10:12 +02:00
Rob Winch d48c32e7f6 Fix reactor-core 3.0.0.RELEASE
Fix the build to work with reactor-core-3.0.0.RELEASE
2016-08-19 12:56:36 -05:00
Rob Winch 3d68806ca1 Consistent reactor-core versions
Previously the IDE (STS) was resolving a different reactor-core
version (3.0.0.BUILD-SNAPSHOT) than the build (3.0.0.RELEASE). This
discrepancy was due to the fact that reactor-netty now brings in
reactor-core 3.0.0.RELEASE. Gradle's version conflict resolution is to use
the latest version. However, the optional dependency on reactor-core
3.0.0.BUILD-SNAPSHOT was making the build path of the IDE use the SNAPSHOT.

This fix leverages a resolutionStrategy to ensure a consistent version of
reactor-core is used throughout the entire project. It also bumps up the
reactor-core version to 3.0.0.RELEASE to be consistent with reactor-netty.
Care is taken to only change 3.x vesion since 2.x is still used within
the codebase.
2016-08-19 12:56:29 -05:00
Stephane Nicoll b183934ed4 Remove reference to PayloadApplicationEvent
Issue: SPR-14594
2016-08-19 14:22:21 +02:00
Stephane Nicoll 74511181de Document support for @ManagedBean
Issue: SPR-14600
2016-08-19 13:52:39 +02:00
Juergen Hoeller 7bb4ab6842 Various @since tags (and varargs on setInterceptors)
(cherry picked from commit 5222489)
2016-08-18 12:58:02 +02:00
Juergen Hoeller 5ee65cd4b1 Updated to JPA 2.1 requirement 2016-08-18 10:17:01 +02:00
Juergen Hoeller 453822817f Protected visibility for configurePathMatch and configureAsyncSupport
Issue: SPR-14599
2016-08-18 10:15:48 +02:00
Juergen Hoeller d2e3a1a4f5 DelegatingWebMvcConfiguration properly delegates extendHandlerExceptionResolvers
Issue: SPR-14599
2016-08-18 09:05:47 +02:00
Juergen Hoeller 53819c472f Updated note on CompilationCustomizer and CompilerConfiguration
Issue: SPR-14585
(cherry picked from commit da56758)
2016-08-17 22:33:21 +02:00
Juergen Hoeller f1ab37cd01 Renamed setDefaultPersistenceUnitRootLocation to setPersistenceUnitRootLocation 2016-08-17 22:12:47 +02:00
Juergen Hoeller b4db161880 Latest dependency updates (Caffeine 2.3.2, RxJava 1.1.9, Jetty 9.4.0.M1) 2016-08-17 22:11:55 +02:00
Juergen Hoeller cf9b4d1e0b Removed duplicate NoHandlerFoundException entry
Issue: SPR-14598
(cherry picked from commit 188e532)
2016-08-17 21:54:40 +02:00
Juergen Hoeller ab0d523cc0 Polishing
(cherry picked from commit 1932a9d)
2016-08-17 21:54:40 +02:00
Stephane Nicoll 1cad98dd31 Add setter for defaultPersistenceUnitRootLocation
This commit adds a setter for the default persistence unit's
defaultPersistenceUnitRootLocation attribute.
2016-08-17 17:40:58 +02:00
Juergen Hoeller 022b013563 Revised NoSuchBeanDefinitionException message for proper array class names
Issue: SPR-14595
2016-08-17 17:13:28 +02:00
Juergen Hoeller 4b06b60007 RootBeanDefinition accepts ResolvableType for target type hint
Issue: SPR-14580
2016-08-17 16:59:16 +02:00
Juergen Hoeller 6a0d9d3d97 Consistent support for CompilationCustomizers as well as custom CompilerConfiguration
Issue: SPR-14585
2016-08-17 11:29:49 +02:00
Juergen Hoeller a1b167a988 Polishing 2016-08-17 00:53:38 +02:00
Juergen Hoeller 433764d217 GroovyScriptFactory supports CompilationCustomizer next to GroovyObjectCustomizer
Issue: SPR-14585
2016-08-17 00:47:50 +02:00
Juergen Hoeller 214c919742 AspectJ bean pointcut supports qualifier match
Issue: SPR-11217
2016-08-17 00:43:41 +02:00
Stephane Nicoll e802f0e731 Clarify use of Ehcache
Since we have a dedicated section regarding Ehcache that is only
applicable to Ehcache 2.x, this commit clarifies that Ehcache 3.x is
JSR-107 compliant and the JCache support should be used with it
rather than attempting to configure the Ehcache 2.x support.
2016-08-16 14:00:13 +02:00
Stephane Nicoll 0d59a15849 Better document #result semantic
Commit 240f254 has introduced support for `java.util.Optional` in the
cache abstraction. If such type is present, the contained value is cached
if it is present.

This new feature slightly changed the semantic of `#result` that was
documented up till this commit as the "return value of the method
invocation". This is no longer true as `#result` for `Optional<T>`
refers to the `T` instance and not the `Optional` instance.

This commit clarifies both the javadoc and the documentation.

Issue: SPR-14587
2016-08-16 13:45:10 +02:00
Stephane Nicoll c17c43a1fe Merge pull request #1132 from igormukhin:patch-1
* pr/1132:
  Add aditional example to CronSequenceGenerator
2016-08-16 11:42:54 +02:00
Igor Mukhin 3f0b458616 Add aditional example to CronSequenceGenerator
CronSequenceGenerator supports comma separated expressions but does not
provide an example for it. This commit adds such an example.

Closes gh-1132
2016-08-16 11:41:37 +02:00
Sam Brannen 669fd80854 Upgrade build to Gradle 3.0
Issue: SPR-14569
2016-08-15 21:26:39 +02:00
Sam Brannen ed467f542a Fix formatting in Web MVC chapter of reference manual 2016-08-15 21:07:35 +02:00
Rob Winch 966baea910 Fix HtmlUnitRequestBuilder merge
Previously invoking HtmlUnitRequestBuilder merge caused the pathInfo of
the parent to be corrupted. This could additional invocations with the
same parent.

This fix ensures that the parent is no longer directly used. Instead,
we create a copy of the parent by merging the parent that was passed in
with the copy.

Fixes SPR-14584
2016-08-12 20:43:01 -05:00
Juergen Hoeller 1ac8e1c949 Polishing
(cherry picked from commit a4a71a8)
2016-08-11 23:50:54 +02:00
Juergen Hoeller 8b5d3559f5 Avoid stack overflow in case of chained factory-bean references to FactoryBean class
Issue: SPR-14551
2016-08-11 22:56:14 +02:00
Juergen Hoeller 6157fad91f PersistenceAnnotationBeanPostProcessor obtains default EntityManagerFactory via getBean(Class) algorithm
Issue: SPR-7549
2016-08-11 22:42:06 +02:00
Juergen Hoeller eeeab27f1f Polishing
(cherry picked from commit 35e247a)
2016-08-10 16:42:21 +02:00
Stephane Nicoll 2a4ee07cb3 Fix typo 2016-08-10 14:23:37 +02:00
Juergen Hoeller 59a24b406a Polishing 2016-08-10 14:20:42 +02:00
Juergen Hoeller a4b6682c3e Consistent spelling for StandaloneMockMvcBuilder's addPlaceholderValue 2016-08-10 14:18:41 +02:00
Stephane Nicoll 02e9477711 Merge pull request #1129 from kduhyun:fix-doc1
* pr/1129:
  Fix typo
2016-08-10 10:44:48 +02:00
wolverine.kim a3062dfe78 Fix typo
Closes gh-1129
2016-08-10 10:44:07 +02:00
Juergen Hoeller fae503d568 MethodBasedEvaluationContext reliably exposes varargs
Issue: SPR-14554
2016-08-09 21:24:38 +02:00
Sebastien Deleuze 106bda7294 Fix NettyDataBuffer#lastIndexOf() 2016-08-09 18:07:10 +02:00
Juergen Hoeller 8acceba641 Polishing
(cherry picked from commit aade2d1)
2016-08-09 12:42:57 +02:00
Juergen Hoeller eae079ac2b Polishing 2016-08-09 10:44:10 +02:00
Juergen Hoeller 47e9360d62 MockClientHttpResponse closes body stream on close()
Issue: SPR-14563
2016-08-09 10:43:50 +02:00
Rossen Stoyanchev 62e08a5ebe Minor update to Spring Web Reactive chapter
Issue: SPR-14565
2016-08-08 16:48:44 -04:00
Rossen Stoyanchev cc288a0c4a Switch back to Reactor 3.0 snapshots 2016-08-08 16:42:30 -04:00
Juergen Hoeller 526ce28ef0 Upgrade to Hibernate ORM 5.2.2 and Undertow 1.4 GA / XNIO 3.4 2016-08-08 16:01:02 +02:00
Juergen Hoeller 36143692ac Consistent use of AvailableSettings instead of Environment
Issue: SPR-14548
2016-08-08 14:48:05 +02:00
Juergen Hoeller d69afaada8 PathEditor tries file system path in case of non-existing resource
Issue: SPR-14549
2016-08-08 13:46:57 +02:00
Juergen Hoeller d128830605 Test injection for @Lookup-declaring bean
Issue: SPR-14550
2016-08-08 13:21:52 +02:00
Juergen Hoeller aeec1245eb ClientWebRequestBuilders documentation fix
Issue: SPR-14561
2016-08-08 13:20:27 +02:00
Sebastien Deleuze 5531e80724 Anticipate reactor.test.TestSubscriber removal
reactor.test.TestSubscriber will not be part of Reactor Core
3.0.0 since it needs to be refactored to fit all the needs
expressed by the users. It is likely to be back later in one
of the Reactor Core 3.0.x releases.

This commit anticipate this removal by temporarily copying
TestSubscriber in spring-core test classes. As soon as
the new TestSubscriber will be available in Reactor Core,
Spring Framework reactive tests will use it again.
2016-08-08 11:24:21 +02:00
Stephane Nicoll e4ccbc964a Polish 2016-08-06 17:42:06 +02:00
Stephane Nicoll 8aadb8d193 Polish Javadoc
Issue: SPR-14552
2016-08-06 17:15:36 +02:00
Sebastien Deleuze e86529ec90 Prevent StackOverflowError in AbstractJackson2HttpMessageConverter
Issue: SPR-14520
2016-08-04 11:20:38 -07:00
Juergen Hoeller fad931d764 Consistent default connection release mode with Hibernate 5.1
Issue: SPR-14548
2016-08-04 03:07:14 +02:00
Juergen Hoeller 8109a8c288 Updated ServletHttpHandlerAdapter usage 2016-08-04 03:04:33 +02:00
Arjen Poutsma dfef4e09da Added HttpHandler contructor argument 2016-08-03 15:39:44 -07:00
Brian Clozel 7af97c38ce Upgrade to Protobuf 3.0.0 2016-08-02 14:57:49 -07:00
Stephane Nicoll 6b616bad9c Merge pull request #1126 from kamilszymanski:expression-lambda
* pr/1126:
  Use abbreviated expression lambda instead of statement lambda
2016-07-30 12:55:21 +02:00
Kamil Szymanski 4aea551e8e Use abbreviated expression lambda instead of statement lambda
Closes gh-1126
2016-07-30 12:54:59 +02:00
Juergen Hoeller 0a5e5776c1 Upgrade to Undertow 1.4 CR4
Issue: SPR-14328
2016-07-28 10:54:14 +02:00
Juergen Hoeller 5ac7a32c8a Raise JDBC driver feature baseline to JDBC 4.0+
Issue: SPR-13826
2016-07-28 10:51:29 +02:00
Juergen Hoeller d96a66ae8f ConfigurationClassParser uses unified ImportStack with chained import analysis
Issue: SPR-14517
2016-07-28 00:06:13 +02:00
Rossen Stoyanchev 460ed307ed Shorten getter for ReactiveAdapterRegistry 2016-07-27 17:03:56 -04:00
Rossen Stoyanchev 143b5c89dd Add support for rx.Completable as return value 2016-07-27 17:00:27 -04:00
Rossen Stoyanchev 79bc227c9d Remove SimpleResultHandler
There is really no need for a result handler dedicated to a void
return value and it's actually problematic to have it.

Each result handler treats void as necessary. For an @ResponseBody
method it means an empty body. For view resolution it means no specific
value was returned and we should procede with selecting a default view
name. Having a dedicated void result handler can interfere with this
especially since view resolution needs to be last in order.

At the same time there are cases when no result handling is needed
and the response is fully handled within the HandlerAdapter. This is
the case with WebHandler and the SimpleHandlerAdapter. For that case
we simply return mono.then(aVoid -> Mono.empty()) which effectively
returns an empty Mono and no result handling follows. The
HandlerAdapter already says you can return no values at all if the
response is fully handled.
2016-07-27 17:00:27 -04:00
Juergen Hoeller 328e04f167 JndiPropertySource defensively skips invalid JNDI lookup for property name with colon in resource-ref mode
Issue: SPR-14518
2016-07-27 22:37:25 +02:00
Rossen Stoyanchev 3ab21741f9 Use Jetty again in SseIntegrationTests 2016-07-27 13:26:51 -04:00
Rossen Stoyanchev 3ffeec97cb Merge pull request #1123 from violetagg/violetagg-flush-last-element 2016-07-27 12:35:23 -04:00
Rossen Stoyanchev d219054b0d Polish 2016-07-27 12:34:31 -04:00
Violeta Georgieva 301528665d Refactor AbstractResponseBodyFlushProcessor states
With the current state machine
- the implementation can hang after the last element when executing
on Jetty.
- in some cases there will be no flush after the last
Publisher<DataBuffer>.
2016-07-27 11:12:00 -04:00
Violeta Georgieva 4798a1eb02 Cancel Subscription when onError is invoked internally
AbstractResponseBodyProcessor.onError and
AbstractResponseBodyFlushProcessor.onError will be invoked when:
- The Publisher wants to signal with onError that there are failures.
Once onError is invoked the Subscription should be considered canceled.
- The internal implementation wants to signal with onError that there
are failures. In this use case the implementation should invoke
Subscription.cancel()
2016-07-27 11:12:00 -04:00
Violeta Georgieva 16939b7bc7 AbstractListenerServerHttpResponse improvements
This commit changes writeWithInternal(Publisher<DataBuffer> body).
It is implemented as writeAndFlushWith(Mono.just(body)).
2016-07-27 11:12:00 -04:00
Juergen Hoeller fffea06056 Upgrade to Netty 4.1.4 2016-07-27 16:22:26 +02:00
Juergen Hoeller 5db449556b Polishing 2016-07-27 16:21:55 +02:00
Juergen Hoeller 316244d2bd Isolated circular import detection for scanned configuration classes
Issue: SPR-14517
2016-07-27 16:21:48 +02:00
Juergen Hoeller fd9e88d372 Skip Animal Sniffer for the time being (since it chokes on JDK 9 bytecode) 2016-07-27 13:44:44 +02:00
Juergen Hoeller 6d5af60a7c Expose DefaultSubscriptionRegistry's cache limit through SimpleBrokerMessageHandler and MessageBrokerRegistry
Issue: SPR-14516
2016-07-27 12:11:58 +02:00
Juergen Hoeller 06edd232b3 Upgrade to AspectJ 1.9 beta 5
Issue: SPR-13344
2016-07-27 12:11:48 +02:00
Juergen Hoeller c5677f725e Upgrade to Jetty 9.3.11 2016-07-26 22:33:21 +02:00
Juergen Hoeller 02374d7450 TransactionAspectSupport avoids hard references to transaction manager beans
Issue: SPR-14511
2016-07-26 21:29:34 +02:00
Juergen Hoeller b9ab895743 Inferred generics for newSetFromMap arrangements
Issue: SPR-13188
2016-07-26 21:26:31 +02:00
Juergen Hoeller e03dea1d64 Polishing 2016-07-26 17:15:19 +02:00
Rossen Stoyanchev 7b564b72a1 Polish Spring Web Reactive content 2016-07-26 10:23:26 -04:00
Juergen Hoeller c13f8419f9 Minor revision of reactive support layout (ahead of 5.0 M1)
DataSourceUtils moved to main core.io.buffer package.
Consistently named Jackson2JsonDecoder/Encoder and Jaxb2XmlDecoder/Encoder.
Plenty of related polishing.
2016-07-26 15:39:32 +02:00
Juergen Hoeller 3d6a5bcd66 Switch to latest published versions of Reactor and RxNetty 2016-07-26 15:37:55 +02:00
Sam Brannen 7ff9f0a8e9 Clean up warnings in spring-orm 2016-07-26 14:02:33 +02:00
Juergen Hoeller 195467083c Drop JpaSystemException(PersistenceException) constructor to avoid ambiguity in HibernateJpaVendorAdapter
Hibernate 5.2's HibernateException extends PersistenceException, leading to a different constructor compiled into the bytecode, breaking compatibility with Hibernate 5.0 at runtime.

Issue: SPR-13827
2016-07-26 01:23:39 +02:00
Juergen Hoeller e4def2f55d Aligned ConcurrentMap declaration with 4.3.x branch 2016-07-26 00:54:53 +02:00
Rossen Stoyanchev 5cf8b695cb Add chapter on Spring Web Reactive support
Issue: SPR-14497
2016-07-25 18:34:39 -04:00
Rossen Stoyanchev af4415e1ba Move up CORS section
The CORS section is now ahead of
"Integrating with other web frameworks" and "WebSocket Support".
2016-07-25 18:34:39 -04:00
Juergen Hoeller c4cc91c009 Upgrade to RxJava 1.1.8 2016-07-25 23:51:05 +02:00
Juergen Hoeller ae28815886 Polishing 2016-07-25 23:27:06 +02:00
Juergen Hoeller 75fc0f8538 Framework build compatible with JDK 9 (even with -target 1.9)
Issue: SPR-13344
2016-07-25 23:26:09 +02:00
Juergen Hoeller 9f2cb3e276 Keep deprecated addCache method (e.g. for Spring Data Redis)
Issue: SPR-14430
2016-07-25 17:47:11 +02:00
Juergen Hoeller 3ab86c10c9 Polishing 2016-07-25 17:43:58 +02:00
Juergen Hoeller 87a89c216c Javadoc revision 2016-07-25 14:21:19 +02:00
Juergen Hoeller c97bfd73ad Reintroduced XMLReaderFactory deprecation markers on JDK 9
Issue: SPR-14486
2016-07-25 14:12:29 +02:00
Juergen Hoeller 01110f678d Upgrade JiBX (and BCEL) towards support of 1.8 bytecode level
This commit also drops the now-unused CUSTOM_COMPILATION test group and the outdated JavaVersion class.

Issue: SPR-10423
2016-07-25 14:10:46 +02:00
Stephane Nicoll 0aeb306b6d Merge pull request #1112 from fisache:master
* pr/1112:
  Polish contribution
  Polish Javadoc
2016-07-25 12:35:14 +02:00
Stephane Nicoll bfa48d551d Polish contribution
Closes gh-1112
2016-07-25 12:34:42 +02:00
fisache 3ccf653174 Polish Javadoc
See gh-1112
2016-07-25 12:30:31 +02:00
Juergen Hoeller dd65f7acfc LinkedCaseInsensitiveMap properly overrides HashMap.clone()
Issue: SPR-14509
2016-07-25 12:08:55 +02:00
Juergen Hoeller 249b798059 Direct reference to JDK 7 AutoCloseable interface
Issue: SPR-13188
2016-07-25 12:06:35 +02:00
Stephane Nicoll c316088dd2 Force UTF-8 encoding
Issue: SPR-11569
2016-07-25 10:12:03 +02:00
Sam Brannen ecbec54106 Upgrade to JUnit 5.0.0-M2
Issue: SPR-13575
2016-07-24 17:10:32 +02:00
Juergen Hoeller ed49ce838e Executable instead of Object for constructor or factory method
Issue: SPR-13188
2016-07-24 15:34:03 +02:00
Juergen Hoeller 4a85309a04 Consistent throwing of BeanNotOfRequiredTypeException even for existing proxy
Issue: SPR-14504
2016-07-24 15:31:00 +02:00
Sam Brannen 2a3e62ddfc Delete unused imports in spring-test 2016-07-23 17:23:32 +02:00
Sam Brannen beb45aac69 Suppress deprecation warning in PersistenceInjectionTests 2016-07-23 17:20:09 +02:00
Sam Brannen 2b6971a20e Clean up deprecation warnings in spring-web 2016-07-23 17:17:50 +02:00
Sam Brannen 76aa7b1cd9 Delete unused imports in spring-web 2016-07-23 17:17:29 +02:00
Sam Brannen cb1b178405 Ensure Reactor & RxJava response extractors compile with Eclipse JDT 2016-07-23 17:15:18 +02:00
Brian Clozel b2e848737c Rename reactor.io.netty -> reactor.ipc.netty 2016-07-23 14:34:12 +02:00
Juergen Hoeller 382a931e7d Polishing 2016-07-22 22:28:20 +02:00
Juergen Hoeller e59a5993f3 Consistent support for multiple Accept headers
Issue: SPR-14506
2016-07-22 22:27:58 +02:00
Brian Clozel 6e54ed0df1 Add missing timeout in web-reactive IntegrationTests 2016-07-22 21:37:51 +02:00
Rossen Stoyanchev 10c90a677c Move http.converter.reactive to http.codec 2016-07-22 14:14:46 -04:00
Arjen Poutsma b0d7625e3e Reactor StringEncoder into CharSequenceEncoder
This commit refactors the StringEncoder to a CharSequenceEncoder, in
order to support StringBuilders, Groovy GStrings, etc.

Issue: https://github.com/spring-projects/spring-reactive/issues/120
2016-07-22 12:47:46 -04:00
Rossen Stoyanchev 0f6505e32f Add timeout settings in SseIntegrationTests 2016-07-22 12:42:35 -04:00
Rossen Stoyanchev 101220bad1 Add ReactiveAdapterRegistry
Issue: SPR-14159
2016-07-22 12:21:28 -04:00
Brian Clozel 1a2ac8ea56 Reactor namespace change io.projectreactor.ipc
Some reactor modules such as reactor-netty were migrated under a new
namespace `io.projectreactor.ipc`.
2016-07-22 15:33:59 +02:00
Arjen Poutsma 436a98ec68 Polishing 2016-07-22 15:32:56 +02:00
Brian Clozel 78b6ba0569 Filter irrelevant nodes in StaxHandler tests 2016-07-21 23:01:55 +02:00
Marius Grama 3635c9dbfe Update xmlunit library to version 2.1.0
xmlunit 2.1.0 is the latest release for xmlunit.
Most of the xmlunit functionality used within spring-framework
was done through the xmlunit 1.x helper class
`org.custommonkey.xmlunit.XMLAssert`.

As of xmlunit 2.0.0 most of the XML comparison methods are done
through hamcrest matchers exposed by the xmlunit-matchers
library. In some cases during the migration, the matchers
had to be customized with custom `NodeMatcher` or
`DifferenceEvaluator` instances in order to keep the assertions
correct (they were performed with xmlunit 1.x previously).

Issue: SPR-14043
2016-07-21 15:04:21 +02:00
Sebastien Deleuze 9fb8a2eb2e Add contextClass resolution to JacksonJsonDecoder
Issue: SPR-14158
2016-07-21 14:57:50 +02:00
Juergen Hoeller 610bdf1cc3 DataSource adapters expose setCatalog/setSchema next to setUsername/setPassword
Issue: SPR-14501
2016-07-21 14:06:40 +02:00
Juergen Hoeller e756a5b54b ResourcePatternUtils.getResourcePatternResolver actually accepts null argument
Issue: SPR-14500
2016-07-21 14:06:30 +02:00
Sebastien Deleuze 74158af1b9 Add JsonView and type resolution support to JacksonJsonDecoder
There is no contextClass support yet, we need to find a way to pass
this information to the codecs.

Issue: SPR-14158
2016-07-21 13:55:59 +02:00
Sebastien Deleuze 903770f008 Add JsonView and type resolution support to JacksonJsonEncoder
Issue: SPR-14158
2016-07-21 13:19:52 +02:00
Brian Clozel 4d035e3ab1 Update Google Protobuf support to 3.0.0
This commit adds support for Google Protobuf 3.0.0 and make some changes
in the additional formats support:
* "com.googlecode.protobuf-java-format:protobuf-java-format" is no
longer required and its required version has been raised to 1.3+
(this lib adds support for JSON, XML, HTML formats)
* "com.google.protobuf:protobuf-java-util" is also now supported for
JSON format

Issue: SPR-13589
2016-07-21 11:38:56 +02:00
Arjen Poutsma 7b2196b408 Add writeAndFlushWith to ReactiveHttpOutputMessage
This commit changes the reactive flushing mechanism to use a newly
introduced writeAndFlushWith(Publisher<Publisher<DataBuffer>>) on
ReactiveHttpOutputMessage instead of using the FlushingDataBuffer.

Issue: https://github.com/spring-projects/spring-reactive/issues/125
2016-07-21 11:08:54 +02:00
Juergen Hoeller 9cc625ee2c Polishing
(cherry picked from commit 5a92aa4)
2016-07-20 23:25:17 +02:00
Juergen Hoeller 28e7c11234 Polishing 2016-07-20 22:41:56 +02:00
Juergen Hoeller 5c72ea915d Upgrade to Jackson 2.8.1 2016-07-20 22:36:22 +02:00
Juergen Hoeller 725fb3219f Polishing 2016-07-20 18:06:31 +02:00
Juergen Hoeller 0e3f0bd9d0 Avoid JDK proxy against CGLIB Factory interface and assert required type when resolving dependency
Issue: SPR-14478
2016-07-20 18:05:51 +02:00
Juergen Hoeller 938b56c0fe BeanWrapperImpl.setBeanInstance correctly exposes root object
Issue: SPR-14474
2016-07-20 18:02:23 +02:00
Sebastien Deleuze 3a4e5d5da8 Fix ParameterizedType + contextClass support in Jackson converter
Issue: SPR-14470
2016-07-20 09:29:23 +02:00
Rossen Stoyanchev b52b56c94e Update to the latest Reactory Netty snapshot 2016-07-19 21:11:07 -04:00
Juergen Hoeller 99be15f58b Revise encoding steps towards use of JDK Charset and StandardCharsets
Issue: SPR-14492
2016-07-19 23:43:06 +02:00
Juergen Hoeller 79d30d8c8a Polishing 2016-07-19 23:42:32 +02:00
Juergen Hoeller adc595b5f1 Avoid dependency on WebUtils for extracting file extension
Issue: SPR-14479
2016-07-19 23:30:33 +02:00
Rossen Stoyanchev 86c659f5c0 Remove isAsyncStarted assertion
Issue: SPR-14444
2016-07-19 16:43:03 -04:00
Juergen Hoeller a4743c07d4 Polishing 2016-07-19 20:09:00 +02:00
Juergen Hoeller fd4b5ac892 Ignore JRuby template tests (not compatible with JDK 9 yet)
Issue: SPR-13344
2016-07-19 19:42:31 +02:00
Juergen Hoeller 88fcd0a2ed Framework build compatible with JDK 9 (tests running against java.base module)
Issue: SPR-13344
2016-07-19 19:37:34 +02:00
Juergen Hoeller d07381e862 Avoid deprecated number constructors on JDK 9
Issue: SPR-13344
2016-07-19 19:25:55 +02:00
Juergen Hoeller 8580483d72 SerializableTypeWrapper reobtains type accessors from declaring interface
Issue: SPR-14487
2016-07-19 19:22:32 +02:00
Juergen Hoeller aaac199e8b Consistently use constructor-based instantiation instead of Class.newInstance / BeanUtils.instantiate
Issue: SPR-14486
2016-07-19 19:21:06 +02:00
Juergen Hoeller b3253ca5e2 Drop mock.staticmock package from spring-aspects
Issue: SPR-14485
2016-07-19 18:56:06 +02:00
Juergen Hoeller 8bb34bc962 Resource.isFile() and JAF MediaTypeFactory
Issue: SPR-14484
2016-07-19 18:53:31 +02:00
Juergen Hoeller 7287baefeb GenericSqlQuery configured with RowMapper instance
Issue: SPR-14489
2016-07-19 18:44:06 +02:00
Juergen Hoeller aae4874b85 Revised spring-orm test suite (no AbstractJpaTests anymore)
Issue: SPR-13515
2016-07-19 17:50:57 +02:00
Juergen Hoeller 91ac0bfefa Reinstated support for spring-beans.dtd (streamlined like xsd)
Issue: SPR-13499
2016-07-19 17:46:17 +02:00
Juergen Hoeller 5ea8c2670e Reinstated tests for implicit aliases
Issue: SPR-14437
2016-07-19 17:26:47 +02:00
Juergen Hoeller 1670b4e154 Reliably pass CurrentTenantIdentifierResolver to SessionFactory
Issue: SPR-14476
2016-07-19 17:25:07 +02:00
Arjen Poutsma 35ce1945e0 Improved DataBufferUtilsTest 2016-07-19 11:11:11 +02:00
Rossen Stoyanchev 4b92bf2af1 Split HttpMessageConverter into ~Reader and ~Writer 2016-07-18 22:16:35 -04:00
Brian Clozel dca80788d4 Fix default origin port in ReactorClientHttpConnector
This commit ensures that a valid port is given to the underlying Netty
client when no port is defined in the URL itself.

By default, port 80 is used by the Reactor Netty client.

Issue: SPR-14477
2016-07-18 21:53:15 +02:00
Rossen Stoyanchev 3e096ce810 Improve javadoc on reactive classes
Ensure type-level Javadoc in every class, comply with guidelines for
80 char on Javadoc, and minor polish.
2016-07-18 14:59:15 -04:00
Brian Clozel 7a0c2422c6 Add client-side exception hierarchy
The `WebClient` has a new exception hierarchy:

* `WebClientException` is the root of all exceptions thrown by the
`WebClient`
* `WebClientResponseException` are all exceptions associated with
specific HTTP response status codes
* `WebClientErrorException` and `WebServerErrorException` are
respectively for 4xx and 5xx HTTP status codes

`ResponseExtractor` implementations are adapted to optionally throw
exceptions if it's impossible to extract the relevant parts of the
response (e.g. extracting the response body if the response is a 404).

This commit also introduces `ResponseErrorHandler`s that take care of
the whole exception mapping infrastructure. Since
`WebClientResponseException`s provide the status, headers and response
body, we also need a dedicated mechanism to extract information from the
response body at that level.

The `BodyExtractors` are responsible for extracting that information
from the exception, given they are provided with all the information
they need; in that case, message decoders are required.

To convey all this new information downstream, the `WebClient` now wraps
the message converters and response error handler instances into a
dedicated `WebClientConfig` object.
2016-07-18 17:33:15 +02:00
Brian Clozel fe79219607 Reorganize spring-web-reactive .gitignore 2016-07-18 17:31:18 +02:00
Arjen Poutsma 041437f3ee Fixed DataBufferUtilsTest on Windows
DataBufferUtilsTests checked for newline characters before, resulting in
failures on Windows.
2016-07-18 17:08:46 +02:00
Stephane Nicoll 03e6eeeadc Fix EJB dependency upgrade 2016-07-18 14:51:03 +02:00
Stephane Nicoll cd6b5f9be0 Fix EJB API coordinates 2016-07-18 13:35:08 +02:00
Stephane Nicoll 53a7027d8b Upgrade to EJB 3.2 2016-07-18 13:21:22 +02:00
Sam Brannen afbd57c8af Upgrade to Gradle 2.14.1
Issue: SPR-14362
2016-07-18 11:35:37 +02:00
Sebastien Deleuze 7ad02490d9 Upgrade build to Gradle 2.14.1 2016-07-18 11:10:55 +02:00
Sebastien Deleuze ceb4c8d8e0 Add netty-buffer temp dependency to spring-web-reactive 2016-07-18 10:20:40 +02:00
Stephane Nicoll c86d49f329 Fix CLA section 2016-07-18 08:28:40 +02:00
Do Nhu Vy a76a6b5c29 Fix broken hyperlink
Closes gh-1114
2016-07-18 08:16:58 +02:00
Fredrik Sundberg d3b051a933 Fix javadoc reference
Method is called nextBackOff() and not nextBackOffMillis().

Closes gh-1115
2016-07-18 08:14:12 +02:00
Rossen Stoyanchev 2029b6e0b7 Disable failing Jetty SSE tests for now
https://github.com/eclipse/jetty.project/issues/730
2016-07-15 17:27:51 -04:00
Juergen Hoeller 111b4ae74e Upgrade to Tomcat 8.5.4 2016-07-15 23:22:17 +02:00
Rossen Stoyanchev 028be2a298 Switch to Reactor 3 snapshots and Netty 4.1.3 2016-07-15 17:16:26 -04:00
Juergen Hoeller dc1664939c Javadoc fixes and pruning of outdated references 2016-07-15 22:12:11 +02:00
Juergen Hoeller f0c397e4e2 Comprehensive Servlet 3.1 support in spring-web and spring-test
Issue: SPR-14467
2016-07-15 22:11:14 +02:00
Sam Brannen 177f4ec3a7 Polish annotation utils 2016-07-15 19:54:53 +02:00
Sam Brannen 53c9584025 Remove obsolete references to @AliasFor in Javadoc for AnnotationAttributes 2016-07-15 19:53:54 +02:00
Sam Brannen 53dd88437e Delete dead code in AnnotationAttributes 2016-07-15 19:51:33 +02:00
Sam Brannen 3f317b7d3f Clean up warnings in spring-web 2016-07-15 18:38:27 +02:00
Sam Brannen 58804da369 Polish Reactor & RxJava response extractors 2016-07-15 17:54:24 +02:00
Sam Brannen 1731460eac Ensure Reactor & RxJava response extractors compile with Eclipse JDT 2016-07-15 17:53:15 +02:00
Sam Brannen 841480596e Clean up warnings in Gradle build 2016-07-15 17:38:35 +02:00
Juergen Hoeller 503f0e3397 Polishing 2016-07-15 17:27:59 +02:00
Juergen Hoeller a0df71e76a ConfigurationClassParser load annotations through source class loader
Issue: SPR-10343
(cherry picked from commit 9e93403)
2016-07-15 17:17:25 +02:00
Juergen Hoeller 3d3407c789 Consistent alias processing behind AnnotatedTypeMetadata abstraction (also for ASM)
Issue: SPR-14427
2016-07-15 13:59:25 +02:00
Juergen Hoeller b1663585dc MessageHeaderAccessor properly removes header even in case of null value
Issue: SPR-14468
2016-07-15 00:15:46 +02:00
Rossen Stoyanchev d2e105f28d Add @Since 5.0 and package-info for reactive classes 2016-07-14 17:40:17 -04:00
Juergen Hoeller e2c7653da4 Correct parameter index boundary in exception message
Issue: SPR-14466
2016-07-14 22:29:14 +02:00
Juergen Hoeller e431624e84 CronSequenceGenerator prevents stack overflow in case of inverted range
Issue: SPR-14462
2016-07-14 21:11:28 +02:00
Juergen Hoeller 6d91d54fc9 StandardTypeConverter initializes default ConversionService against volatile field
Issue: SPR-14465
2016-07-14 21:10:24 +02:00
fisache 9aa35a8b5f Polish doc
Closes gh-1108
2016-07-14 19:15:38 +02:00
Arjen Poutsma 3e47fccf2b Propagate IOExceptions in Servlet bridge 2016-07-14 12:30:35 -04:00
Arjen Poutsma 4390cd0c2b Fixed Jaxb2CollectionHttpMessageConverterTests
- Added Woodstox before Aalto in the spring-web build, so that Woodstox
   is used as StAX implementation, and not the less featured Aalto.
 - Hardcoded Aalto dependency in XmlEventDecoder, instead of relying on
   the StAX XMLInputFactory.
2016-07-14 12:30:35 -04:00
Rossen Stoyanchev 5d1b542698 Move spring-web-reactive classes to spring-web 2016-07-14 12:30:35 -04:00
Rossen Stoyanchev 2e8326220b Move spring-web-reactive classes to spring-core 2016-07-14 12:30:30 -04:00
Rossen Stoyanchev 1022683d1c Fix compiler warnings 2016-07-14 12:18:47 -04:00
Rossen Stoyanchev cb798726bd Update build for spring-web-reactive module 2016-07-14 12:18:39 -04:00
Rob Winch 934bc4f953 Merge spring-reactive 2016-07-14 11:03:32 -05:00
Sam Brannen fd008405a1 Note in TEL: before/after test exec. callbacks don't work w/ JUnit 4 rules
Issue: SPR-4365
2016-07-14 15:46:54 +02:00
Sam Brannen 3fa88c2b56 Document suppressed exception support in TestContextManager
Issue: SPR-14459
2016-07-14 15:43:18 +02:00
nkjackzhang e2b8a786ff Polish doc
Closes gh-1110
2016-07-14 11:56:46 +02:00
Stephane Nicoll ff738e7670 Polish contribution
Closes gh-1070
2016-07-14 11:12:06 +02:00
spodgurskiy f075aac7f9 Fix MethodBasedEvaluationContext.lazyLoadArguments
This commit fix a potential `ArrayIndexOutOfBoundsException` if
`lazyLoadArguments` is called with an empty variable argument.

See gh-1070
2016-07-14 10:58:21 +02:00
Juergen Hoeller dd65689e0a MethodParameter.equals accepts subclasses pointing to same target declaration again
Issue: SPR-14438
2016-07-14 09:51:37 +02:00
Juergen Hoeller 04e9c2bf0c Aspect actually applies in PersistenceExceptionTranslationPostProcessorTests
Issue: SPR-14457
2016-07-13 22:31:41 +02:00
Juergen Hoeller adbc592f50 Unwrap JPA PersistenceException on flush failure (for Hibernate 5.2)
Issue: SPR-14457
2016-07-13 22:30:52 +02:00
Juergen Hoeller ddb4117233 HibernateExceptionTranslator converts JPA exceptions as well (for Hibernate 5.2)
Issue: SPR-14455
2016-07-13 22:24:38 +02:00
Sam Brannen adfea826cc Configure JUL/log4j for JUnit 5 in spring-test
Issue: SPR-14431
2016-07-13 22:06:46 +02:00
Sam Brannen 833deadddc Ensure test fails for the correct reason
Prior to this commit, a dynamic test in
FailingBeforeAndAfterMethodsSpringExtensionTestCase was failing but for
the wrong reason. Namely, the @Configuration class was private which
resulted in an IllegalStateException being thrown, when in fact
an AssertionFailedError was expected.

This commit addresses this by introducing an explicit check for an
AssertionFailedError.

Issue: SPR-4365
2016-07-13 21:10:47 +02:00
Sam Brannen 7ec85a3c3b Support suppressed exceptions in the TestContext framework
Prior to this commit, if multiple TestExecutionListener 'after' methods
threw an exception, only the first such exception was rethrown.
Subsequent exceptions were logged, but there was no way to access or
process them other than via the log file.

This commit addresses this shortcoming by making use of the support for
suppressed exceptions introduced in Java 7. Specifically, if multiple
TestExecutionListener 'after' methods throw an exception, the first
exception will be rethrown with subsequent exceptions suppressed in the
first one.

Issue: SPR-14459
2016-07-13 20:29:01 +02:00
Sam Brannen 5f176f50d3 Polishing 2016-07-13 18:18:40 +02:00
Sam Brannen 6162e30f3c Clean up warnings in AsyncTests 2016-07-13 16:39:49 +02:00
Juergen Hoeller 8ccd727c9a AbstractHandlerMethodMapping adds type+method info to getMappingForMethod exceptions
Issue: SPR-14452
2016-07-13 15:42:34 +02:00
Juergen Hoeller 84afc601b8 Configurable UrlPathHelper in PathExtensionContentNegotiationStrategy
This commit also aligns ResourceUrlProvider's and RequestMappingInfo's UrlPathHelper setter/getter signatures.

Issue: SPR-14454
2016-07-13 15:14:42 +02:00
Arjen Poutsma 56e50d6d68 Moved body processor to writeWithInternal()
Moved ResponseBodyProcessor creation from constructor to
writeWithInternal(), in preparation of supporting both
Publisher<DataBuffer> as well as Publisher<Publisher<DataBuffer>>.
2016-07-13 12:04:40 +02:00
Arjen Poutsma 7519d1de41 Moved log4j config to test tree
Moved log4j.properties from the main source tree to the test tree.
2016-07-13 09:56:45 +02:00
Arjen Poutsma f82f17d7f7 Moved Servlet Publisher and Processor
In preparation of supporting both Publisher<DataBuffer> and
Publisher<Publisher<DataBuffer>> as response body, moved
RequestBodyPublisher and ResponseBodyProcessor into
ServletServerHttpRequest and ServletServerHttpResponse respectively.
2016-07-13 09:53:39 +02:00
Arjen Poutsma 392a1660a4 Polishing 2016-07-13 09:53:39 +02:00
Arjen Poutsma e64907eed8 Removed ServletAsyncContextSynchronizer 2016-07-13 09:53:39 +02:00
Arjen Poutsma d2fce24eb4 Introduced ResponseBodyWriteResultPublisher
Refactored Publisher<Void> in AbstractResponseBodyProcessor into
separate ResponseBodyWriteResultPublisher.
2016-07-13 09:53:39 +02:00
Rossen Stoyanchev e91c1cd5a7 Merge pull request #1106 from darklynx/streaming_response_test 2016-07-12 17:50:40 -04:00
Rossen Stoyanchev 01a63dd84d Polish AsyncTests 2016-07-12 17:49:55 -04:00
Vladimir L 7da63c57b3 tests for asynchronous processing if controller returns StreamingResponseBody 2016-07-12 17:44:10 -04:00
Brian Clozel e906a78e0f Move server testing infrastructure to test sources 2016-07-12 17:36:30 +02:00
Sam Brannen c341b39f71 Move "What's New" reference manual chapter to the wiki
A "What's New" page has been created in the Spring Framework wiki:

https://github.com/spring-projects/spring-framework/wiki/What's-New-in-the-Spring-Framework

This commit therefore links to the new wiki page from the appendix of
the reference manual and deletes the existing "What's New" chapter from
the reference manual.

Issue: SPR-14449
2016-07-12 17:35:49 +02:00
Sam Brannen 68b3bc0394 Use Supplier<String> support in Assert in spring-test
This commit makes use of the new Supplier<String> variants of utility
methods in org.springframework.util.Assert within the spring-test
module.

Issue: SPR-14450
2016-07-12 16:41:03 +02:00
Sam Brannen 264f5860a8 Use Supplier<String> support in Assert in spring-core
This commit makes use of the new Supplier<String> variants of utility
methods in org.springframework.util.Assert within the spring-core
module.

Issue: SPR-14450
2016-07-12 16:41:03 +02:00
Sam Brannen 17dd5dd22d Introduce Supplier<String> support in Assert util
Prior to this commit, utility methods in
org.springframework.util.Assert accepted String arguments for custom
error messages. Such Strings are evaluated (e.g., concatenated)
eagerly, and for performance reasons, it was therefore not always
possible to make use of these utility methods. Consequently, there are
several places in the code base that "inline" identical functionality
in order to lazily evaluate error message concatenation and avoid an
unnecessary performance penalty. This leads to verbose code like the
following.

if (!contextPath.startsWith("/")) {
    throw new IllegalArgumentException("contextPath '" + contextPath +
    "' must start with '/'.");
}
if (contextPath.endsWith("/")) {
    throw new IllegalArgumentException("contextPath '" + contextPath +
    "' must not end with '/'.");
}

This commit addresses this shortcoming by introducing Supplier<String>
variants of all utility methods in org.springframework.util.Assert that
allow custom error messages to be evaluated lazily via a lambda
expression that is only evaluated if the assertion fails. This results
in a simplification of the previous examples as follows.

Assert.isTrue(contextPath.startsWith("/"), () -> "contextPath '" +
    contextPath + "' must start with '/'.");
Assert.isTrue(!contextPath.endsWith("/"), () -> "contextPath '" +
    contextPath + "' must not end with '/'.");

Issue: SPR-14450
2016-07-12 16:41:03 +02:00
Sam Brannen 3d4338f555 Clean up warnings in spring-core 2016-07-12 16:41:03 +02:00
Brian Clozel 147a35f4f1 Polish AntPathMatcher.setTrimTokens javadoc
Issue: SPR-14247
2016-07-12 14:47:18 +02:00
Arjen Poutsma d736245f28 Changed from interval() to intervalMillis() 2016-07-12 13:25:18 +02:00
Stephane Maldini c2c7e3b596 Polish timed operators and remove useTimer() 2016-07-12 12:13:50 +01:00
Brian Clozel 3ce49819f2 Update link to Spring CLA in CONTRIBUTING doc 2016-07-12 10:20:03 +02:00
Stephane Nicoll c425e774a3 Polish 2016-07-12 09:10:34 +02:00
Stephane Nicoll 2ee42192b3 Merge pull request #1105 from fisache:master
* pr/1105:
  Polish doc
2016-07-12 08:54:58 +02:00
fisache 55ad5a448e Polish doc
Closes gh-1105
2016-07-12 08:52:15 +02:00
Stephane Nicoll 825a5ec029 Merge pull request #1107 from nkjackzhang:patch-5
* pr/1107:
  Polish doc
2016-07-12 08:51:02 +02:00
nkjackzhang 1fb93044af Polish doc
Closes gh-1107
2016-07-12 08:50:35 +02:00
Rossen Stoyanchev b66cc71d66 Merge RequestMappingIntegrationTests refactoring 2016-07-11 21:09:35 -04:00
Rossen Stoyanchev aa47616be2 Split TestRestController into use-case sub-classes 2016-07-11 18:08:11 -04:00
Rossen Stoyanchev 7e07fb16d8 Split RequestMappingIntegrationTests into sub-classes 2016-07-11 18:08:11 -04:00
Rossen Stoyanchev 35f791acf8 Extract base class for RequestMappingIntegrationTests 2016-07-11 18:08:11 -04:00
Rossen Stoyanchev 6fde86903d Declare HTTP method mappings TestRestController 2016-07-11 18:07:55 -04:00
Rossen Stoyanchev aa1397b8ba Polish method order in RequestMappingIntegrationTests 2016-07-11 18:07:46 -04:00
Sam Brannen 22345f7c25 Upgrade tests to EhCache 2.10+
Issue: SPR-13794
2016-07-11 17:17:03 +02:00
Sam Brannen f7f37cdb1b Introduce before/after test execution callbacks in the TCF
This commit introduces 'before' and 'after' test execution callbacks in
the Spring TestContext Framework. Specifically, this set of commits
introduces the following.

- beforeTestExecution() and afterTestExecution() callbacks in the
  TestExecutionListener API

- beforeTestExecution() and afterTestExecution() callbacks in
  TestContextManager

- RunBeforeTestExecutionCallbacks and RunAfterTestExecutionCallbacks
  JUnit 4 statements that are used by the SpringJUnit4ClassRunner

- Documentation in the class-level Javadoc for SpringMethodRule stating
  that before/after test execution callbacks cannot be supported with
  JUnit 4 Rules

- Support for JUnit Jupiter's BeforeTestExecutionCallback and
  AfterTestExecutionCallback extension APIs in the SpringExtension for
  JUnit 5

- Support for before/after test execution callbacks in
  AbstractTestNGSpringContextTests for TestNG

Issue: SPR-4365
2016-07-11 15:45:35 +02:00
Sam Brannen 80018c67e7 Introduce before/after test execution support in the SpringExtension
Issue: SPR-4365
2016-07-11 15:44:51 +02:00
Sam Brannen da89332840 Introduce before/after test execution support in SpringJUnit4ClassRunner
Issue: SPR-4365
2016-07-11 15:13:40 +02:00
Sam Brannen 3da5fbe995 Introduce before/after test execution support in AbstractTestNGSpringContextTests
Issue: SPR-4365
2016-07-11 15:13:40 +02:00
Sam Brannen 087efa668c Introduce before/after test execution callbacks in TestContextManager
Issue: SPR-4365
2016-07-11 15:13:40 +02:00
Sam Brannen 5302566cbb Introduce before/after test execution callbacks in TestExecutionListener
Issue: SPR-4365
2016-07-11 15:13:40 +02:00
Stephane Nicoll 11ed26584d Polish 2016-07-11 10:50:44 +02:00
Stephane Nicoll 15c3cdd48d Fix NoOpCache handling of get(key,callable)
This commit fixes the method that takes a Callable to actually always
invoke it rather than returning null.

Issue: SPR-14445
2016-07-11 10:34:27 +02:00
Sam Brannen 629b95bd5c Ensure TestContextManager always tracks after-class exception
This commit fixes a minor bug introduced in 0adc4921ed.

Issue: SPR-14447
2016-07-10 16:04:00 +02:00
Rossen Stoyanchev 407715b89e Helpers for get/post in RequestMappingIntegrationTests
This commit replaces the current helper methods in
RequestMappingIntegrationTests with generic helper methods to perform
HTTP GET and POST requests.

This results in more transparent code that shows the exact HTTP
inputs and outputs and is also more flexible to change for
variations in testing.
2016-07-08 12:17:36 -04:00
Sam Brannen 966d951329 Remove deprecated @TransactionConfiguration & TxCfgAttributes
Issue: SPR-14430
2016-07-08 18:16:44 +02:00
Sam Brannen 57c43f4273 Delete unused import 2016-07-08 17:40:42 +02:00
Sam Brannen d6d4251550 Utilize default methods in TestExecutionListener
Issue: SPR-14432
2016-07-08 17:38:41 +02:00
Sam Brannen a0cad5c48f Use streams and lambdas in spring-test where feasible
Issue: SPR-13188
2016-07-08 17:38:40 +02:00
Sam Brannen 8fff1c2ac0 Polishing 2016-07-08 17:18:14 +02:00
Sam Brannen 80216c243d Annotate ContextCustomizer[Factory] with @FunctionalInterface
Issue: SPR-14432
2016-07-08 17:17:25 +02:00
Juergen Hoeller e8b5374d87 Require EhCache 2.10+
Issue: SPR-13794
2016-07-08 16:28:24 +02:00
Rossen Stoyanchev d84b989025 Update notes on deps for broker relay 2016-07-08 09:20:49 -04:00
Juergen Hoeller c43e7497c1 Fixed typo: "occured"->"occurred" 2016-07-08 15:12:16 +02:00
Juergen Hoeller 23c2b6ad41 Added PathEditor for NIO file system resolution
Issue: SPR-14436
2016-07-08 14:58:38 +02:00
Brian Clozel 99697118d8 Add RxJava1 support for request building/extracting
This commit adds the required infrastructure to build HTTP requests as
well as extracting relevant information from HTTP responses using the
RxJava 1.x API, where Observable and Single don't extend Publisher.
2016-07-08 14:22:48 +02:00
Brian Clozel 4892436efe Refactor HTTP client contracts
This commit refactors the `ClientHttpRequestFactory` into an
`ClientHttpConnector` abstraction, in order to reflect that
`ClientHttpRequest`s only "exist" once the client is connected
to the origin server.

This is why the HTTP client is now callback-based, containing all
interactions with the request within a
`Function<ClientHttpRequest,Mono<Void>>` that signals when it's done
writing to the request.

The `ClientHttpRequest` contract also adopts `setComplete()`
and promotes that method to the `ReactiveHttpOutputMessage` contract.

This commit also adapts all other APIs to that change and fixes a few
issues, including:

* use `HttpMessageConverter`s instead of `Encoders`/`Decoders`
* better handle type information about request content publishers
* support client cookies in HTTP requests
* temporarily remove the RxNetty client support
2016-07-08 14:20:07 +02:00
Sam Brannen 40b2d26bd4 Avoid reflection for @Repeatable look-ups
Issue: SPR-13188
2016-07-08 13:21:31 +02:00
Juergen Hoeller 61db8e9f1e DigestUtils processes InputStream with buffered read instead of full copy
Issue: SPR-14427
2016-07-08 12:20:49 +02:00
Brian Clozel b5bce1f017 Update after reactor.core.converter.Converters changes
Reactor's `DependencyUtils` has been renamed to `Converters` and
all the `from` converter methods have been disambiguated to
`fromPublisher`, `toPublisher`.
2016-07-08 12:00:06 +02:00
Stephane Nicoll 2bf9bc312e Remove Guava cache support
This commit removes `GuavaCache` and support classes. Caffeine supersedes
the caching support in the Google Guava library with an actively maintained
Java 8+ version in standalone form.

As it is the only Guava feature Spring framework integrates with, this
commit removes effectively any reference to Guava.

Issue: SPR-13797
2016-07-08 10:57:05 +02:00
Arjen Poutsma 799bb64275 Merge pull request #135 from violetagg/ondataavailable-concurrency
Refactor AbstractRequestBodyPublisher states
2016-07-08 09:45:05 +02:00
Violeta Georgieva d68232c880 Refactor AbstractRequestBodyPublisher states
The state machine is refactored in order to solve various concurrency
issues.
2016-07-08 09:31:51 +03:00
Rossen Stoyanchev d7a43d2003 Polish tests 2016-07-07 23:04:27 -04:00
Rossen Stoyanchev 7534092ef3 Comprensive support for empty request body
This commit adds support for handling an empty request body with both
HttpEntity where the body is not required and with @RequestBody where
the body is required depending on the annotation's required flag.

If the body is an explicit type (e.g. String, HttpEntity<String>) and
the body is required an exception is raised before the method is even
invoked or otherwise the body is passed in as null.

If the body is declared as an async type (e.g. Mono<String>,
HttpEntity<Mono<String>>) and is required, the error will flow through
the async type. If not required, the async type will be passed with no
values (i.e. empty).

A notable exception is rx.Single which can only have one value or one
error and cannot be empty. As a result currently the use of rx.Single
to represent the request body in any form effectively implies the body
is required.
2016-07-07 15:58:06 -04:00
Rossen Stoyanchev a584311178 Fix StringDecoder#decodeToMono issue with empty input
Before this change decodeToMono always created a StringBuilder to
aggregate resulting in an "" (empty string) rather than an empty
Mono for an empty input stream.

Now we aggregate in the DataBuffer instead and then decode to String.
2016-07-07 15:58:06 -04:00
Rossen Stoyanchev 1e1e2f8b1b Support HttpEntity method arguments
The RequestBodyArgumentResolver has been refactored to have a shared
base class and tests with the new HttpEntityMethodArgumentResolver.

An HttpEntity argument is not expected to have an async wrapper because
the request headers are available immediately. The body however can be
asynchronous, e.g. HttpEntity<Flux<String>>.
2016-07-07 15:58:06 -04:00
Brian Clozel 4c3c54463c Upgrade build to Spring 5.0.0-BUILD-SNAPSHOT
* update bean validation API version
* MethodParameter now validates indices, see 39e3f2ebf6
* `getCharSet()` is now `getCharset()`
2016-07-07 18:11:04 +02:00
Sam Brannen 7e783dd91f Delete temporary MethodParameterFactory solution
SPR-14055 introduced first-class support for the Java 8 Parameter API.

This commit therefore replaces the MethodParameterFactory with use of
the new SynthesizingMethodParameter.forParameter(Parameter) factory
method.

Issue: SPR-13575
2016-07-07 13:02:49 +02:00
Sam Brannen 862fb2af5f Upgrade to JUnit 5.0.0-M1
Issue: SPR-13575
2016-07-07 12:49:46 +02:00
Stephane Nicoll 0f589fc49c Merge pull request #1100 from nkjackzhang:patch-1
* pr/1100:
  Remove trailing whitespaces
  Add the injection point for the Provider
2016-07-07 10:35:27 +02:00
Stephane Nicoll 1103a9cd16 Remove trailing whitespaces
Closes gh-1100
2016-07-07 10:34:50 +02:00
nkjackzhang 6aeaa1976d Add the injection point for the Provider
See gh-1100
2016-07-07 10:31:49 +02:00
Juergen Hoeller 6aa5931e28 Polishing 2016-07-07 01:05:25 +02:00
Juergen Hoeller a1f5fb53db Java 8 getParameterCount() instead of getParameterTypes().length
Issue: SPR-13188
2016-07-07 01:04:24 +02:00
Juergen Hoeller 39e3f2ebf6 MethodParameter supports Java 8 Executable/Parameter and validates parameter indexes
Also, equals insists on the same class now, differentiating from SynthesizingMethodParameter.

Issue: SPR-14055
Issue: SPR-13456
Issue: SPR-14438
2016-07-07 00:37:52 +02:00
Rossen Stoyanchev 9cc01fc185 Add @RequestBody tests 2016-07-06 14:10:51 -04:00
Rossen Stoyanchev 54bfbbc607 Rename decodeOne->decodeToMono and readOne->readMono 2016-07-06 12:38:05 -04:00
Juergen Hoeller da9c24c41e Polishing 2016-07-06 18:11:33 +02:00
Rossen Stoyanchev 6525504e17 Restore local vars in JacksonJsonEncoder 2016-07-06 09:35:25 -04:00
Juergen Hoeller 102dc8a4dd Polishing 2016-07-06 15:29:15 +02:00
Juergen Hoeller 19e5a34f9f Restored binary compatibility with Hibernate 5.0/5.1's Query type
Issue: SPR-14425
2016-07-06 15:20:09 +02:00
Juergen Hoeller 5890758fd0 Avoid canonicalName call for already-seen bean name
Issue: SPR-14433
2016-07-06 15:12:18 +02:00
Juergen Hoeller 76dedd7ca2 FactoryBean, BeanPostProcessor and HandlerInterceptor variants declared with default methods
Issue: SPR-14432
2016-07-06 15:10:08 +02:00
Rossen Stoyanchev 9ee4f6ee30 Polish tests 2016-07-06 08:59:46 -04:00
Stephane Nicoll e4b0486c5a Add @FunctionalInterface on candidate interfaces
Issue: SPR-14432
2016-07-06 14:32:13 +02:00
Arjen Poutsma b0de99bc8c Refactor ResponseBodySubscriber to Processor
This commit changes the AbstractResponseBodySubscriber into a
AbstractResponseBodyProcessor<DataBuffer, Void>, so that the processor
can be used as a return value for writeWith.

Additional, this commit no longer closes the response after an eror
occurred.

This fixes #59.
2016-07-06 13:18:42 +02:00
Stephane Nicoll 912b63ad44 Merge pull request #1099 from nkjackzhang:patch-5
* pr/1099:
  Polish doc
2016-07-06 11:20:54 +02:00
nkjackzhang 7dfbc16f1f Polish doc
Closes gh-1099
2016-07-06 11:20:32 +02:00
Arjen Poutsma c85d1dc126 Merge pull request #133 from violetagg/onwritepossible-concurrency
AbstractResponseBodySubscriber improvements
2016-07-06 10:37:49 +02:00
Violeta Georgieva 7763391e84 AbstractResponseBodySubscriber improvements
When the thread is writing to the response in
RECEIVED.onWritePossible(), the execution may stop because isReady()
returned false. In this case the buffer is partially written.
When there is partially written case:
1. The state will be changed from WRITING to RECEIVED
2. A check for "write possible" will be performed:
  - If onWritePossible event has been already called by the web
  container while in WRITING state then this check will trigger
  RECEIVED.onWritePossible() because isReady() will be true and the
  writing will continue.
  - Otherwise the writing will be resumed when the web container sends
  onWritePossible event.
2016-07-06 10:14:05 +03:00
Rossen Stoyanchev 55193194c2 Polish tests 2016-07-05 20:39:56 -04:00
Rossen Stoyanchev 9c438a8f78 Fix failing test 2016-07-05 18:20:31 -04:00
Rossen Stoyanchev 33b6dca2a6 Polish tests 2016-07-05 18:14:47 -04:00
Juergen Hoeller 7dda9fbd8c Drop JasperReports support
Issue: SPR-13294
2016-07-05 23:06:15 +02:00
Juergen Hoeller 355c6f0715 Upgrade to JMS 2.0 and JCA 1.7
Issue: SPR-13793
2016-07-05 22:18:19 +02:00
Juergen Hoeller bc2c22d51e Streamline XML namespace support towards unversioned schemas
This commit also removes support code for outdated options which were only available in older schema versions.

Issue: SPR-13499
2016-07-05 20:50:03 +02:00
Juergen Hoeller 12d373659a Upgrade to Undertow 1.4 CR3 (and Jackson 2.8 GA)
This commit also renames WebSocketIntegrationTests to WebSocketHandshakeTests.

Issue: SPR-14328
2016-07-05 20:47:53 +02:00
Juergen Hoeller acdb43f470 Remove remaining JRuby and Commons Pool test resources
Issue: SPR-14429
2016-07-05 20:47:39 +02:00
Sam Brannen 2bae0613a3 Ensure code compiles with Eclipse JDT 2016-07-05 19:19:09 +02:00
Sam Brannen 1391248ea6 Introduce log4j 2 for Spring's test suite
This commit adds a test runtime dependency on log4j 2 for every project
and migrates all log4j.properties files to log4j2-test.xml files.

Issue: SPR-14431
2016-07-05 19:19:09 +02:00
Rossen Stoyanchev 7af7a55ede Polish and simplify JacksonJsonEncoder 2016-07-05 12:02:47 -04:00
Rossen Stoyanchev 2068f667f3 Expose getStatusCode from ServerHttpResponse 2016-07-05 11:10:36 -04:00
Sam Brannen 9a9551bf18 Make JUnit Jupiter support classes package private
Issue: SPR-13575
2016-07-05 17:09:18 +02:00
Sam Brannen 045c678622 Clean up warnings in spring-test 2016-07-05 17:09:18 +02:00
Rossen Stoyanchev 7401d10f91 Polish AbstractServerHttpResponse 2016-07-05 11:06:02 -04:00
Stephane Nicoll 00d2606b00 Explicit type can be replaced by <>
Issue: SPR-13188
2016-07-05 17:00:34 +02:00
Stephane Nicoll 3096888c7d Better synchronization in ConcurrentMapCache
Issue: SPR-13810
2016-07-05 16:44:07 +02:00
Juergen Hoeller 9b9f3714ae JRuby script template tests run against JRuby 9.1.2.0 now
Issue: SPR-14429
2016-07-05 16:34:52 +02:00
Juergen Hoeller b5db5d3aac Broadly remove deprecated core classes and methods
Issue: SPR-14430
2016-07-05 15:52:49 +02:00
Juergen Hoeller 0fc0ce78ae Drop deprecated dependencies on Log4j, JRuby, JExcel, Burlap, Commons Pool/DBCP
This commit also removes outdated support classes for Oracle, GlassFish, JBoss.

Issue: SPR-14429
2016-07-05 15:46:53 +02:00
Juergen Hoeller fb5a096ca2 Require Undertow 1.3 byte buffer pool
Issue: SPR-13495
2016-07-05 15:31:40 +02:00
Sam Brannen 5f53a60120 Restrict visibility of internal MethodParameterFactory
Issue: SPR-14055
2016-07-05 15:20:01 +02:00
Sam Brannen 0da93ad219 Reinstate -Werror compiler argument in Gradle build
Commit 0900808 resolved the previous issue by moving the warning
suppression from the method parameter to the method itself.

Issue: SPR-13188
2016-07-05 15:07:32 +02:00
Sam Brannen 016fa0eb39 Upgrade test to Hibernate 5.2 2016-07-05 11:05:23 +02:00
Juergen Hoeller 51252ebbca Avoid defensive checks against Java 8 API (java.util.Optional etc)
This commit also fixes broken javadoc links and code references.

Issue: SPR-13188
2016-07-05 02:09:00 +02:00
Juergen Hoeller adb935db79 Restore special spring-aspects javadoc treatment 2016-07-04 23:59:00 +02:00
Juergen Hoeller f38a4b9040 Build update for pruned modules 2016-07-04 23:38:25 +02:00
Juergen Hoeller 54004e0d78 Upgrade to JPA 2.1+ and Bean Validation 1.1+; remove native support for Hibernate 3.6 and 4.x
Issue: SPR-13481
Issue: SPR-13827
2016-07-04 23:37:23 +02:00
Juergen Hoeller 69ec437fbc Drop native OpenJPA support
Issue: SPR-14426
2016-07-04 23:35:19 +02:00
Juergen Hoeller d341624e91 Drop JDO support
Issue: SPR-14130
2016-07-04 23:34:48 +02:00
Juergen Hoeller 2b3445df81 Drop Portlet MVC support
This commit also removes the corresponding deprecated Servlet MVC variant and updates DispatcherServlet.properties to point to RequestMappingHandlerMapping/Adapter by default.

Issue: SPR-14129
2016-07-04 23:33:47 +02:00
Juergen Hoeller ae0b7c26c5 Drop Servlet 2.5 runtime compatibility
Issue: SPR-13189
2016-07-04 23:31:21 +02:00
Juergen Hoeller ff6ead1fff Remove Velocity support
Issue: SPR-13795
2016-07-04 23:30:58 +02:00
Juergen Hoeller 4027bda168 Remove Tiles 2 support
Issue: SPR-13229
2016-07-04 23:30:11 +02:00
Juergen Hoeller d0aa607200 Remove XMLBeans support
Issue: SPR-13796
2016-07-04 23:29:29 +02:00
Juergen Hoeller 770f0c0661 Require Undertow 1.3.5+, Tyrus 1.11+, Jetty 9.3+, Tomcat 8.5+
Issue: SPR-13495
2016-07-04 23:27:07 +02:00
Juergen Hoeller ccf791b63f Deprecate OkHttp 2.x support
Issue: SPR-14344
2016-07-04 23:23:28 +02:00
Juergen Hoeller 81057a2cee Require EhCache 2.10+
Issue: SPR-13794
2016-07-04 23:22:32 +02:00
Juergen Hoeller 447835465f Remove support for deprecated AbstractHttpClient class
Issue: SPR-14422
2016-07-04 23:21:42 +02:00
Juergen Hoeller 0900808820 Method-level @SuppressWarnings("unchecked") for generic varargs 2016-07-04 23:20:41 +02:00
Sam Brannen 873fc53a2f Introduce support for JUnit 5 in the TestContext framework
This commit introduces initial support for JUnit Jupiter (i.e., the new
programming and extension models in JUnit 5) in the Spring TestContext
Framework.

Specifically, this commit introduces the following.

- SpringExtension: an implementation of multiple extension APIs from
  JUnit Jupiter that provides full support for the existing feature set
  of the Spring TestContext Framework. This support is enabled via
  @ExtendWith(SpringExtension.class).

- @SpringJUnitConfig: a composed annotation that combines
  @ExtendWith(SpringExtension.class) from JUnit Jupiter with
  @ContextConfiguration from the Spring TestContext Framework.

- @SpringJUnitWebConfig: a composed annotation that combines
  @ExtendWith(SpringExtension.class) from JUnit Jupiter with
  @ContextConfiguration and @WebAppConfiguration from the Spring
  TestContext Framework.

Issue: SPR-13575
2016-07-04 22:40:58 +02:00
Sam Brannen 54e3ea8d37 Enable Java 8 source and target compatibility in Gradle build
Issue: SPR-13188
2016-07-04 16:28:26 +02:00
Sebastien Deleuze 8690464a9b Remove @Ignore on streamResult() test
This test was fixed by previous commit that allows to
JSON encode correctly streams with more than 2 elements.
2016-07-04 15:51:44 +02:00
Sebastien Deleuze 7ed03d01c6 Fix JacksonJsonEncoder for streams with more than 2 elements 2016-07-04 15:45:32 +02:00
Sam Brannen 3aefa136fd Upgrade build to Gradle 2.14
Issue: SPR-14362
2016-07-04 15:24:38 +02:00
Sam Brannen 3be0ea9128 Suppress deprecation warning in spring-test 2016-07-04 15:20:52 +02:00
Sam Brannen fb1eb00b4a Update @since tag in Eclipse template to 5.0 2016-07-04 15:15:19 +02:00
Sebastien Deleuze c1518c3fde Avoid exception while setting the status code of a committed response
Before this commit, it was not possible to set the status code of an
HTTP response without throwing an exception if it was already
committed. The consequence was a lot of errors in the logs for long
lived HTTP exchanges like Server-Sent Events for example.

After this commit, ServerHttpResponse#setStatusCode() returns
true if the operation succeeded and false if the status code has not
been set because the response has already been committed.

In term of implementation, that makes status code managed
consistently with headers and cookies:
AbstractServerHttpResponse#setStatusCode() stores the status
code that will be effectively set later in the response lifecycle by
the HTTP server via AbstractServerHttpResponse#writeStatusCode()
when the response will be committed.
2016-07-04 13:16:19 +02:00
Stephane Nicoll 19622e3b2d Upgrade copyright 2016-07-04 12:42:54 +02:00
Spring Buildmaster b6a1680df5 Next Development Version 2016-07-04 09:33:06 +00:00
Sebastien Deleuze b7b6704c7e Support rx.Completable 2016-07-04 11:05:49 +02:00
Sebastien Deleuze a1d4fe6938 Upgrade dependencies 2016-07-04 10:17:54 +02:00
Sebastien Deleuze f254680f29 Remove unused imports 2016-07-04 10:06:02 +02:00
Sebastien Deleuze 0f01729b27 Allow to configure Tomcat baseDir
This commit also set Tomcat baseDir to java.io.tmpdir for
integration tests in order to avoid creation of temporary directories
in the project root.
2016-07-04 09:52:39 +02:00
Sebastien Deleuze b7b0313c21 Speed up RequestMappingIntegrationTests
Reactor Core + Spring Reactive now handle correctly
shorter interval for the stream result test.
2016-07-04 08:45:47 +02:00
Rossen Stoyanchev 8c76581442 Provide rich type information to ConversionService
When using the ConversionService to check and bridge to and from
reactive types we now generallly provide the full type information
available from method signatures. However that full type information
is not always necessary such as when we perform additional checks on
the generics of the reactive type (e.g. Mono<ResponseEntity>).

This allows us to switch to use DefaultFormattingConversionService
instead of GenericConversionService while also ensuring that the
CollectionToObjectConverter doesn't think it can convert List<?> to
any reactive type.

The ObjectToObjectConverter can also interfere because it is smart
enough to find the "from(Publisher<?>)" method on Flux and Mono.
To make up for that on the response side we now check if a type
is assignable to Publisher first in which case it is a simple cast.

In turn that means we don't need a PublisherToFluxConverter which can
be problematic in its own right because it can convert from Mono to
Flux which technically doesn't lose data but switches stream semantics.

Issue: #124, #128
2016-07-03 21:55:32 -04:00
Rossen Stoyanchev fb2e796048 HandlerResult now requires MethodParameter as input
HandlerAdapter's should always be able to provide a MethodParameter
which in turn ensures that HandlerResultHandler's have full type
information from method declarations.

This commit also introduces ResolvableMethod for use in tests to make
it easy to obtain MethodParameter return types.

Issue: #128
2016-07-03 21:54:20 -04:00
Rossen Stoyanchev dffd6d674a Shorten returnValueType name in HandlerResult 2016-07-01 18:00:31 -04:00
Rossen Stoyanchev df64262db6 Complete reactive conversion support refactoring
This commit ensures stream semantics (Flux vs Mono) are adhered to also
on the target side.
2016-07-01 17:42:36 -04:00
Rossen Stoyanchev 71f4dff011 Polish validation in RequestBodyArgumentResolver 2016-07-01 17:42:36 -04:00
Rossen Stoyanchev a68ff94fbc Polish "decodeOne" related changes 2016-07-01 17:42:36 -04:00
Sebastien Deleuze 917a2fb9d0 Add Decoder#decodeOne()
This commit adds a Decoder#decodeOne() method in order
to handle correctly the streaming versus one value
deserialization based on the type provided by the user.

For example, if a List parameter is provided in a controller
method, Jackson will be called once, while if the user provides
a Flux or an Observable parameter, Jackson will be called for
each element.
2016-07-01 17:42:36 -04:00
Sebastien Deleuze 12d7b78169 Refactor reactive type conversion support
This commit replaces Reactive Streams converters for RxJava1 and
CompletableFuture with Reactor specific ones. The results in conversion
that preserves stream semantics, i.e. Mono vs Flux.

For example this is allowed:
Flux -> Observable
Mono -> Single
Mono -> CompletableFuture

This is not allowed:
Flux -> Single
Mono -> Observable
Flux -> CompletableFuture

As a result it is now possible to check through the ConversionService
if a target type to convert to is a stream of many or of one which is
useful for decoding purposes.

The commit also adds PublisherToFluxConverter to allow conversion from
raw Publisher to Flux. The reverse is not necessary since Flux is a
Publisher and it's a no-op conversion.
2016-07-01 17:41:37 -04:00
Rossen Stoyanchev 952395192f Collapse core.codec and core.codec.support into one 2016-06-30 16:12:36 -04:00
Rossen Stoyanchev 2f2546c8a4 Simplify initialization of WebSession Mono
The DefaultWebSessionManager now uses Mono.defer to protect the call
to getSession from parsing session cookies immediately. This allows
pre-initializing the Mono<WebSession> upfront vs using a lock.
2016-06-30 16:00:49 -04:00
Rossen Stoyanchev 4e2802338a Add MockWebSessionManager 2016-06-30 15:53:58 -04:00
Rossen Stoyanchev 43a1ea6bac Remove class checked in by mistake 2016-06-30 14:10:15 -04:00
Rossen Stoyanchev 39253b314a Fix tests by moving JAXB2 types back into sub-package 2016-06-30 14:09:09 -04:00
Rossen Stoyanchev 6d089cdc08 Move remaining JAXB2 test files from core to http 2016-06-30 13:48:41 -04:00
Sebastien Deleuze b115f1885d Move JSON and XML codecs to org.springframework.http.codec 2016-06-30 17:01:50 +02:00
Sebastien Deleuze 8d654584a8 Make JsonObjectDecoder package private 2016-06-30 16:30:16 +02:00
Arjen Poutsma 3403a6ca38 Merge pull request #127 from violetagg/ondataavailable-state
AbstractRequestBodyPublisher.onDataAvailable improvement
2016-06-30 16:07:01 +02:00
Violeta Georgieva ea18e73803 AbstractRequestBodyPublisher.onDataAvailable improvement
When in state DATA_AVAILABLE if there are simultaneous invocations of
AbstractRequestBodyPublisher.RequestBodySubscription.request and
ReadListener.onDataAvailable, the first one will process the available
data, the second one should not throw an exception because thus it will
signal to web container that there are problems while there are not.
2016-06-30 16:56:15 +03:00
Arjen Poutsma 1d48e7c5b9 Allow to set response status on Undertow
Refactored Undertow support to register a response listener only when
the body is written to, as opposed to registering it at startup. The
reason for this is that getting the response channel from the
HttpServerExchange commits the status and response, making it impossible
to change them after the fact.

Fixed issue #119.
2016-06-30 15:27:08 +02:00
Arjen Poutsma 2418ff0ad4 Merge pull request #126 from violetagg/onwritepossible-state
Make AbstractResponseBodySubscriber.onWritePossible thread-safe
2016-06-30 11:07:50 +02:00
Violeta Georgieva e545b20289 Make AbstractResponseBodySubscriber.onWritePossible thread-safe
When there are simultaneous invocations of onWritePossible, only the
first one should succeed. This can happens when
AbstractResponseBodySubscriber.onNext and
WriteListener.onWritePossible() are called respectively by the
application and the web container.
2016-06-30 11:59:38 +03:00
Rossen Stoyanchev e9d8152ab2 Port fix for SPR-14397
This is a port of the following commit, adapted for Java 8+:
https://github.com/spring-projects/spring-framework/commit/89396ff01ff159aa7df18e332f3888cf9ce3dc20
2016-06-29 17:34:45 -04:00
Rossen Stoyanchev 478b4149f7 Add netty-buffer as a compile dependency
This is a temporary measure for M1 as the dependency will go away once
issue #116 is addressed.
2016-06-29 12:04:51 -04:00
Sebastien Deleuze 76baf85cfb Polish JacksonJsonDecoder 2016-06-29 14:22:21 +02:00
Sebastien Deleuze 1f2fbba89b Make JsonObjectDecoder mandatory in JacksonJsonDecoder 2016-06-29 10:34:46 +02:00
Arjen Poutsma 92821d9300 Merge pull request #123 from violetagg/onsubscribe-state
Make AbstractResponseBodySubscriber.onSubscribe thread-safe
2016-06-29 09:51:30 +02:00
Violeta Georgieva 0605c0f3be Make AbstractResponseBodySubscriber.onSubscribe thread-safe
When there are simultaneous invocations of onSubscribe, only the first one should succeed, the rest should cancel the provided subscriptions
2016-06-29 10:47:23 +03:00
Arjen Poutsma 11ed847aca AbstractRequestBodyPublisher improvements
Reactored Servlet 3.1 and Undertow request support
(AbstractResponseBodySubscriber) to use an internal state machine,
making thread-safity a lot easier.
2016-06-28 16:29:02 +02:00
Arjen Poutsma 3a681fba89 AbstractResponseBodySubscriber improvements
- AbstractResponseBodySubscriber now checks if the current state is
   expected before changing to a new state.
 - Included comments by @violetagg
2016-06-28 11:33:58 +02:00
Sebastien Deleuze 13b6f4fee4 Add SseEventEncoder to WebReactiveConfiguration 2016-06-28 11:11:45 +02:00
Rossen Stoyanchev cbe2cbcc88 CodecHttpMessageConverter supports a default charset 2016-06-27 09:34:19 -04:00
Rossen Stoyanchev 67175005e3 Add failing Jackson-related response body tests 2016-06-27 09:01:22 -04:00
Rossen Stoyanchev 699b057126 ResponseBodyResultHandler ignores ResponseEntity
Currently ResponseEntityResultHandler is ordered lower than
ResponseBodyResultHandler by default whch means a ResponseEntity
should not be picked by the ResponseBodyResultHandler.

However as it is easy to have both ResponseEntity and @ResponseBody
e.g. in @RestControler (or even by mistake) and in general it makes
sense for ResponseBodyResultHandler to explicitly recognize and
ignore the ResponseEntity return type.
2016-06-27 09:00:46 -04:00
Sebastien Deleuze c24b504a07 Speedup flushing tests 2016-06-27 08:59:24 +02:00
Rossen Stoyanchev 0ff7df8b5c Improve default content type handling
We now also check the default content type if the content type is
application/octet-stream as we do today.

Uncommented failing test that now passes.
2016-06-24 18:14:11 -04:00
Rossen Stoyanchev 351e834716 Polish 2016-06-24 18:03:56 -04:00
Rossen Stoyanchev 95751acb33 Support async wrappers for ResponseEntity
Before this commit only ResponseEntity with async body was supported,
e.g. ResponseEntity<Mono<String>>

This commit also adds suppport for an asyn wrapper around,
e.g. Mono<ResponseEntity<String>.
2016-06-24 17:17:17 -04:00
Rossen Stoyanchev 49bb83c0ec Refactor view resolution tests 2016-06-24 15:39:45 -04:00
Rossen Stoyanchev cae8800183 Refactor @ResponseBody and ResponseEntity tests
Introduce separate test classes for each base class in the hierarchy
above @ResponseBody and ResponseEntity result handlers.

Also start porting existing unit test cases for @ResponseBody and
ResponseEntity return value handlers.
2016-06-24 13:25:41 -04:00
Sebastien Deleuze 3fe87ee225 Change SseEvent#mimeType to SseEvent#mediaType 2016-06-24 17:21:01 +02:00
Sebastien Deleuze e6a0b39df5 Remove SseHttpMessageConverter
CodecHttpMessageConverter is now suitable for SSE since it now
handles default content type.
2016-06-24 17:11:29 +02:00
Sebastien Deleuze 59d3721a40 Support default content type in CodecHttpMessageConverter 2016-06-24 17:09:33 +02:00
Arjen Poutsma 52325a21ff Fixed Undertow flush support
Reactored Servlet 3.1 and Undertow response support into an
AbstractResponseBodySubscriber that uses an internal state machine,
making thread-safity a lot easier.
2016-06-24 15:28:12 +02:00
Sebastien Deleuze 6b3d5f1bc5 Turn FlushingDataBuffer to an empty DataBuffer 2016-06-24 15:28:12 +02:00
Sebastien Deleuze 3c80c19c19 Take in account Rossen and Arjen feedbacks 2016-06-24 15:28:12 +02:00
Arjen Poutsma 81496624a9 Fixed Servlet flush
Servlet flush will now occur on the next possible write if it cannot be
done immediately.
2016-06-24 15:28:12 +02:00
Sebastien Deleuze 9004812231 Add Server-Sent Events support
Flux<SseEvent> is Spring Web Reactive equivalent to Spring MVC
SseEmitter type. It allows to send Server-Sent Events in a reactive way.
Sending Flux<String> or Flux<Pojo> is equivalent to sending
Flux<SseEvent> with the data property set to the String or
Pojo value. For example:

@RestController
public class SseController {

	@RequestMapping("/sse/string")
	Flux<String> string() {
		return Flux.interval(Duration.ofSeconds(1)).map(l -> "foo " + l);
	}

	@RequestMapping("/sse/person")
	Flux<Person> person() {
		return Flux.interval(Duration.ofSeconds(1)).map(l -> new Person(Long.toString(l), "foo", "bar"));
	}

	@RequestMapping("/sse-raw")
	Flux<SseEvent> sse() {
		return Flux.interval(Duration.ofSeconds(1)).map(l -> {
			SseEvent event = new SseEvent();
			event.setId(Long.toString(l));
			event.setData("foo\nbar");
			event.setComment("bar\nbaz");
			return event;
		});
	}
}
2016-06-24 15:27:26 +02:00
Sebastien Deleuze aeb35787d7 Add flushing support
This commit add flushing support thanks to the FlushingDataBuffer
wrapper that allows to identify the elements that should trigger a
flush.
2016-06-24 15:23:26 +02:00
Rossen Stoyanchev 9aa6f5caac Add support for ResponseEntity result handling 2016-06-21 17:27:52 -04:00
Sebastien Deleuze 59b7c25003 Use ResolvableType instead of raw Class in JacksonJsonDecoder 2016-06-21 16:48:18 +02:00
Sebastien Deleuze b5ec47d360 Polishing 2016-06-20 17:10:31 +02:00
Sebastien Deleuze a0e2231779 Use specified ResolvableType in JacksonJsonEncoder
This commit also fixes an issue in the HTTP client that used the
wrapper type instead of the element type. As a consequence, due
to type erasure, we now have to specify the type of the content
in DefaultHttpRequestBuilder#contentStream().
2016-06-20 16:23:02 +02:00
Sebastien Deleuze 5141a198d9 Avoid using deprecated methods in StringEncoder 2016-06-20 13:28:59 +02:00
Rossen Stoyanchev 551b7cd60e Add global Validator bean to WebReactiveConfiguration 2016-06-10 16:06:12 -04:00
Rossen Stoyanchev 2f8baac4e0 Validation support for @RequestBody with @Validated 2016-06-10 15:52:29 -04:00
Rossen Stoyanchev 0a2c3c3744 Polish RequestBodyArgumentResolver 2016-06-10 14:53:19 -04:00
Arjen Poutsma ea21643a29 Various DataBuffer improvements
- Added fromIndex parameter to indexOf and lastIndexOf
- Moved DataBuffer.tokenize to StringEncoder, as that's the only place
  it's used.
2016-06-10 15:27:56 +02:00
Arjen Poutsma 622d11dbce Upgraded Netty to 4.1.0.Final 2016-06-10 15:21:36 +02:00
Arjen Poutsma 54c2e866c3 Renamed getSupportedMimeTypes() in [En|De]coder
Renamed getSupportedMimeTypes() to getEncodableMimeTypes and
getDecodableMimeTypes. This will allow for both Encoder and Decoder to
be implemented in the same class.

This issue fixes #113.
2016-06-10 11:00:28 +02:00
Arjen Poutsma b5394a1f50 Polishing 2016-06-10 10:39:26 +02:00
Arjen Poutsma 61240ee517 Fixed javadoc typo 2016-06-09 13:34:51 +02:00
Rossen Stoyanchev 4fd80bbb67 Add Jackons decoder tests related List vs Flux 2016-06-08 18:10:27 -04:00
Rossen Stoyanchev 22a6ca1f41 Remove Pojo from tests that shouldn't depend on it
The Pojo test class from the codec package will end up in spring-core.
This commit ensures it is used only from classes that also belong to
spring-core.
2016-06-08 16:09:54 -04:00
Rossen Stoyanchev 4e3c439593 Polish Encoder and Decoder 2016-06-08 16:04:52 -04:00
Rossen Stoyanchev a8e5e40d97 @RequestBody raises 415 if no matching converter 2016-06-07 22:14:59 -04:00
Rossen Stoyanchev 36765f0f52 Add protected method to reactive config 2016-06-06 22:24:46 -04:00
Rossen Stoyanchev 7ec85b21bb Remove unused test class 2016-06-06 17:44:08 -04:00
Rossen Stoyanchev 0a88d5983a Polish ResponseBodyArgumentResolver 2016-06-06 17:43:47 -04:00
Rossen Stoyanchev 5c236e1edf Update to latest Reactor snapshot 2016-06-06 10:12:11 -04:00
Rossen Stoyanchev 03b474edfe Add Web Reactive Java config 2016-06-06 09:50:46 -04:00
Rossen Stoyanchev 505569c992 Add Encoder constructor to HttpMessageConverterView 2016-06-06 09:50:16 -04:00
Rossen Stoyanchev b45a48d0fc Support for custom argument resolvers 2016-06-06 09:49:59 -04:00
Rossen Stoyanchev a163938758 Message converters are configurable 2016-06-03 17:56:08 -04:00
Rossen Stoyanchev b20ea75766 Update to latest Reactor snapshot 2016-06-03 17:56:08 -04:00
Rossen Stoyanchev 03a997c9d4 Remove outdated DataBufferFactory properties
Removed in favor of accessing the factory from the response.
2016-06-01 18:07:54 -04:00
Rossen Stoyanchev 431fedccc7 Upgrade to RxJava 1.1.5
After the fix for ReactiveX/RxNetty#509 we can remove the workaround
to concatenate with an empty Observable for the request body and
upgrade to the latest RxJava 1.1.5.

Issues: #103
2016-06-01 17:32:05 -04:00
Sebastien Deleuze 8cf5ea91f8 Sync with TestSubscriber changes in reactor-core 2016-06-01 17:55:53 +02:00
Rossen Stoyanchev 65246f8cfd Remove FIXME on retain in ReactorServerHttpRequest
The converters release so this is the right thing to do, not a
temporary fix.
2016-06-01 10:17:12 -04:00
Rossen Stoyanchev a40a8b06bf Polish view resolution 2016-05-31 22:14:17 -04:00
Rossen Stoyanchev 8cc72b320b View resolution with content negotiation
ViewResolutionResultHandler and ResponseBodyResultHandler now share
a common base class ContentNegotiatingResultHandlerSupport that
supports content negotiation.

For view resolution we compare against the supported media types of
resolved View instances, which may include default View's delegating
to an HttpMessageConverter (e.g. JSON, XML, rendering).
2016-05-31 21:51:24 -04:00
Rossen Stoyanchev 5db1a54ff0 Add HttpMessageConverterView 2016-05-31 17:49:21 -04:00
Rossen Stoyanchev a37b2e3a84 Refactor View contract
View now returns Mono<Void> rather than Flux<DataBuffer> which aligns
more closely with the reactive HttpMessageConverter vs the Encoder.

The change was prompted by the upcoming implementation of a View that
delegates to an existing HttpMessageConverter e.g. for JSON, XML.

The resulting change also brings the reactive View closer in spirit to
the View from spring-webmvc which returns void.
2016-05-31 16:50:38 -04:00
Rossen Stoyanchev f8a7024b73 Polish SimpleResultHandler 2016-05-31 16:50:32 -04:00
Rossen Stoyanchev 1b308cffbf Introduce base class for ResponseBodyResultHandler
The ContentNegotiatingResultHandlerSupport base class encapsulates the
logic for content negotiation needed for both @ResponseBody and view
resolution result handling.
2016-05-31 16:33:01 -04:00
Stephane Maldini 3f7178ba9f Sync Reactor 2016-05-31 13:00:51 +01:00
Stephane Maldini 7fc3031c7a update after Schedulers change 2016-05-31 11:11:38 +01:00
Sebastien Deleuze 3f80b4ab2e Polish 2016-05-30 15:26:55 +02:00
Sebastien Deleuze 97155f1a30 Rename ReactiveHttpOutputMessage.setBody() to writeWith() 2016-05-30 15:09:37 +02:00
Rossen Stoyanchev 58307ebac4 Support Model-related return values
This commit adds support for Model-related return values types such as
Map, Model, @ModelAttribute annotated, and non-simple types, which
helps to clarify the logic in ViewResolutionResultHandler.
2016-05-27 20:22:58 -04:00
Rossen Stoyanchev 33c5a19769 Handle unresolved view name 2016-05-27 15:22:22 -04:00
Rossen Stoyanchev a72462cd8c Polish view resolution tests 2016-05-27 15:22:22 -04:00
Rossen Stoyanchev f7d4688b84 Improve 404 "handler not found" handling
Remove handler inserted at the end to generate error in favor of doing
the same using the otherwiseIfEmpty operator.
2016-05-27 15:21:28 -04:00
Brian Clozel c6ed12297f Add Host property in HttpServerSupport
And change the defaults to:

* "0.0.0.0" for the host
* any available port, starting at 8080
2016-05-27 15:50:41 +02:00
Arjen Poutsma 03fe209862 Renamed ReactiveHttpOutputMessage dataBufferFactory() method to bufferFactory() 2016-05-27 10:37:04 +02:00
Arjen Poutsma d36286c7d1 Renamed DataBufferAllocator to DataBufferFactory 2016-05-27 09:51:42 +02:00
Arjen Poutsma 6f46164727 Changed reduceToSingleBuffer to splitOnNewline
In order to be more "reactive", changed StringDecoder's default from
merging all buffers in the stream to a single buffer into splitting the
buffers along newline (\r, \n) characters.
2016-05-27 09:22:57 +02:00
Arjen Poutsma 74abe92804 Added DataBuffer indexOf and lastIndexOf
This commit introduces DataBuffer.indexOf(IntPredicate) and
lastIndexOf(IntPredicate), for finding the index of a byte in a
DataBuffer.
It also introduces DataBufferUtils.tokenize, which tokenizes a
DataBuffer into separate tokens, given a delimiter function.
2016-05-27 09:22:57 +02:00
Rossen Stoyanchev f0c8c4e7a4 Add request path based default view name support 2016-05-26 18:08:18 -04:00
Rossen Stoyanchev 793638e610 Rename ViewResolverResultHandler to ViewResolution~ 2016-05-26 17:48:35 -04:00
Rossen Stoyanchev 8b99c51969 Fix compiler warnings 2016-05-26 17:37:39 -04:00
Rossen Stoyanchev eb9fe235fe Properly handle Mono.empty() for view resolution
This commit ensures correct handling for Mono.empty() return value
where the declared return type is Mono<String> or Mono<View>.
2016-05-26 17:34:52 -04:00
Rossen Stoyanchev 91a5759cf5 Polish result handlers default order 2016-05-26 16:17:56 -04:00
Rossen Stoyanchev bc782902d7 Remove java.util.Optional from View contract 2016-05-26 16:00:08 -04:00
Rossen Stoyanchev 4d04bd5690 Consolidate view resolution under result.view
While View and ViewResolver play the same role as in spring-webmvc they
are now abstracted behind the HandlerResultHandler abstraction so that
top-level contracts don't reference them and the DispatcherHandler is
also unaware of their existence.

Furthermore view resolution and response body handling which are now at
the same level of abstraction (each is a HandlerResultHandler) will
also share code for content negotiation, so it makes sense for them to
be side by side.

This commit moves the reactive.view package to reactive.result.view
with the View and ViewResolver contracts (previously in the top-level
reactive package) also moving there.
2016-05-26 15:55:22 -04:00
Rossen Stoyanchev 318b15c321 Polish 2016-05-26 13:39:16 -04:00
Rossen Stoyanchev 2263954ad7 Respect produces condition in @ResponseBody algorithm 2016-05-26 13:34:08 -04:00
Rossen Stoyanchev a017e2848a Rename ContentTypeResolver to RequestedContentTypeResolver 2016-05-26 11:05:48 -04:00
Rossen Stoyanchev 37404d081e Use ContentTypeResolver for content negotiation 2016-05-26 10:52:19 -04:00
Rossen Stoyanchev 2292e46b04 Update empty return value ResponseBody handling
When a null is returned from an @ResponseBody method, rather than
returning Mono.empty() immediately, convert it to Mono.empty() and
apply the same processing.

Currently that doesn't make a practical difference but it's more
accurate to do it this way. Eventually it may mean the possibility
to turn empty values into something through an extension point
as we do with ResponseBodyAdvice in Spring MVC today.
2016-05-25 17:35:58 -04:00
Rossen Stoyanchev 91d063899b Polish ResponseBody result handling 2016-05-25 17:34:15 -04:00
Rossen Stoyanchev da3b21b020 Fix typo in build script 2016-05-24 15:41:51 -04:00
Rossen Stoyanchev 662e093fbb Temporarily fix RxJava at 1.1.1 to avoid hanging tests
Issue #103
2016-05-24 15:32:18 -04:00
Sebastien Deleuze 5cbc29e61e Upgrade to Tomcat 8.5.2 2016-05-17 13:24:36 +02:00
Stephane Maldini a108268241 fix emit 2016-05-12 11:24:09 +01:00
Stephane Maldini efa5b876fe fix emit 2016-05-12 09:36:28 +01:00
Stephane Maldini f0d28f4b09 fixme : force retain() on incoming bytebuf content 2016-05-06 23:52:23 +01:00
Rossen Stoyanchev 59217243ee Add viewNames for UrlBasedViewResolver 2016-05-05 21:16:21 -04:00
Rossen Stoyanchev aadbf1d8a6 Order ViewResolver's 2016-05-05 20:53:12 -04:00
Rossen Stoyanchev 4d9126a474 Add support for more annotated method arguments
- @PathVariable
 - @RequestHeader
 - @RequestParam
 - @CookieValue
 - @Value
 - @RequestAttribute
 - @SessionAttribute
2016-05-03 23:41:52 -04:00
Stephane Maldini 4e8c21e85a Sync Reactor SignalEmitter 2016-05-04 01:37:11 +01:00
Stephane Maldini 04f47da15e Synchronize Reactor Flux#create / Flux#generate changes 2016-05-03 23:06:07 +01:00
Arjen Poutsma b71f143dfd Polishing 2016-05-03 16:33:56 +02:00
Stephane Maldini b2d9e7c28d Split FluxProcessor factories into individual Processor, remove confusing factories 2016-05-02 22:56:18 +01:00
Stephane Maldini eb21f3ab0a remove lift() 2016-04-28 22:38:26 +01:00
Arjen Poutsma cc8b2109a9 Removed DataBufferUtils.toInputStream
Replaced all usages of toInputStream with non-blocking alternatives.
2016-04-28 16:12:35 +02:00
Arjen Poutsma 8aa7b42cbf Resolved DataBuffer leaks in codec package 2016-04-28 15:21:12 +02:00
Stephane Maldini 6fbaa7dbb4 compile time issue 2016-04-27 22:08:51 +01:00
Stephane Maldini 09fdc8a384 update consume to subscribe
update after to then (WIP flux)
2016-04-27 21:06:45 +01:00
Arjen Poutsma 72b66c9715 Introduction of PooledDataBuffer
This commit introduces a pooled data buffer as a subtype of DataBuffer,
as well as various utility methods related to reference counting.

Additionally, Crelease calls have been introduced throughout the
codebase to properly dispose of pooled databuffers.
2016-04-26 15:08:52 +02:00
Arjen Poutsma 92e1bff768 Merge pull request #84 from mp911de/charsetdecoder-in-stringdecoder
Use CharsetDecoder to decode a DataBuffer into a String.
2016-04-25 14:51:48 +02:00
Arjen Poutsma ad0a4e0cf8 Introduce AbstractSingleValueEncoder
This commit introduces the AbstractSingleValueEncoder, an abstract base
class for encoders that only handle a single value.
2016-04-22 13:06:00 +02:00
Arjen Poutsma 9ed4bff4a9 Fixed DataBufferUtils.takeUntilByteCount 2016-04-22 13:01:18 +02:00
Arjen Poutsma 52c9b3b235 Introduce ResourceEncoder and ResourceDecoder
This commit introduces the ResourceEncoder and ResourceDecoder, and uses
these in ResourceHttpMessageConverter as a non-zero-copy fallback
method.
2016-04-22 09:54:51 +02:00
Rossen Stoyanchev df7c8e550d Updates to WebHandler support
Rename two classes each adapting to WebHandler to avoid confusing them:
1. HttpWebHandlerAdapter adapts from the low level HttpHandler to any
WebHandler (e.g. DispatcherHandler).
2. SimpleHandlerAdapter adapts the plain WebHandler for use within the
DispatcherHandler.

This commit also fixes an issue in WebHttpHandlerBuilder to ensure that
WebExceptionHandler's are inserted before and not after WebFilter's.
2016-04-21 20:35:47 -04:00
Rossen Stoyanchev a23f792052 Add SimpleUrlHandlerMapping
This commit replaces the temporary SimpleUrlHandlerMapping with
a full-featured one.
2016-04-21 17:04:43 -04:00
Arjen Poutsma 53f8b84bcc Polishing 2016-04-21 12:46:57 +02:00
Arjen Poutsma df3cf69a96 Polishing 2016-04-21 12:23:44 +02:00
Rossen Stoyanchev dd607d3e53 BadRequestStatusException -> ServerWebInputException
The renaming makes it clear this exception is for use where 400 error
applies within a Spring web application where the error may be
associated with a MethodParameter, a BindingResult, and so on.

There is no need for BadRequestStatusException which can be expressed
with ResponseStatusException(HttpStatus.BAD_REQUEST, "reason").
2016-04-20 13:39:42 -04:00
Arjen Poutsma 54eeb2cdb1 Merge pull request #97 from poutsma/zero_copy_response
@ResponseBody Resource support
2016-04-20 16:28:08 +02:00
Arjen Poutsma 804f69c8b6 Wrapping up zero-copy support
This commit wraps up the previous commits:

 - It uses HttpMessageConverter in the web.reactive.server package instead of Encoder/Decoder.
 - It introduces tests for the Resource @ResponseBodies.
2016-04-20 16:27:11 +02:00
Arjen Poutsma 3c486c02ab Reactive HttpMessageConverter
This commit introduces a reactive version of the HttpMessageConverter.
During the implementation of zero-copy support, it became apparent that
it was ueful to have a common abstraction between client and server that
operated on HttpMessages rather than DataBuffers.

Two HttpMessageConverter implementations are provided:
 - The CodecHttpMessageConverter, based on Encoder/Decoder.
 - The ResourceHttpMessageConverter, using zero-copy if available.
2016-04-20 16:27:11 +02:00
Arjen Poutsma 451e296a78 Zero-copy support
This commit introduces support for zero-copy file transfers in the HTTP
response, through the ZeroCopyHttpOutputMessage subinterface of
ReactiveHttpOutputMessage.
2016-04-20 16:27:04 +02:00
Arjen Poutsma 7b7f833004 Various MimeType and MediaType improvements 2016-04-20 13:34:30 +02:00
Arjen Poutsma d626b5e833 Various DataBuffer improvements
This commit introduces two DataBuffer improvements:

 - The capability to read a Flux<DataBuffer> from an input stream or
   channel.

 - The capability to limit a Publisher<DataBuffer> to publish up until a
   given maximum byte count.
2016-04-20 13:30:40 +02:00
Rossen Stoyanchev a173c78d98 Add getAttribute to WebSession and ServerWebExchange 2016-04-19 17:34:08 -04:00
Rossen Stoyanchev d041b73c10 Polish 2016-04-19 16:43:50 -04:00
Rossen Stoyanchev 8ca5b830b1 Remove dependency on WebUtils 2016-04-19 16:41:32 -04:00
Rossen Stoyanchev 9c40b65b70 Improve error message for unsatisfied param conditions 2016-04-19 16:28:32 -04:00
Rossen Stoyanchev 6b7360fed1 Apply new ResponseStatusException hierarchy
This commit replaces use of the existing ServletException-based
exceptions with the new ones from ~.web.server.
2016-04-19 16:02:22 -04:00
Rossen Stoyanchev 3849fd6b5b Remove DispatcherHandlerExceptionMapper
No need to translate to response status codes any more and no need for
an exception handling mechanism at this level.
2016-04-19 16:02:22 -04:00
Rossen Stoyanchev 8f0fe713f5 Add concrete ResponseStatusException sub-classes 2016-04-19 16:02:22 -04:00
Rossen Stoyanchev 66707835fe Move ResponseStatusException into server sub-package 2016-04-19 16:02:22 -04:00
Stephane Maldini 00eff4b611 Rename SchedulerGroup to Computations and its methods to avoid confusion 2016-04-19 09:08:38 +01:00
Rossen Stoyanchev 92c72b93a6 Switch defaults for ContentTypeResolver
Now that we have a CompositeContentTypeResolverBuilder with built-in
defaults, we switch to those defaults in places where a
ContentTypeResolver is used.
2016-04-18 17:56:19 -04:00
Rossen Stoyanchev 4af99473ff Add CompositeContenTypeResolver and a builder
This is the equivalent of the existing ContentNegotiationManager +
ContentNegotiationManagerFactoryBean
2016-04-18 17:43:20 -04:00
Rossen Stoyanchev 1f283acb98 Add path extension and parameter ContentTypeResolver's 2016-04-18 17:43:20 -04:00
Rossen Stoyanchev 9ffc0b5e65 Update FileExtensionContentTypeResolver
Rename to MappingContentTypeResolver and replace "fileExtension" with
"key" in methods to be more general (e.g. file extension or query
param). Also switch from List to Set for the return values.
2016-04-18 17:43:20 -04:00
Stephane Maldini 7d60c2767d Normalize returns with Scheduler factories in SchedulerGroup 2016-04-18 21:26:12 +01:00
Rossen Stoyanchev 0f44fedd19 Complete RequestMappingHandlerMapping
This commit adds RequestMappingInfoHandlerMapping and
RequestMappingHandlerMapping with support equivalent to that in
spring-webmvc.
2016-04-18 13:07:23 -04:00
Stephane Maldini 0e5a892bad Use ByteBuf instead of Buffer in reactor-netty 2016-04-18 17:49:32 +01:00
Stephane Maldini ad9d8c28fe Polish reactor-ipc/netty contracts 2016-04-17 14:50:20 +01:00
Stephane Maldini 0a3396c5b2 Polish contracts 2016-04-16 01:05:30 +01:00
Stephane Maldini 9a4b98d2e9 Update HttpClient with Inbound/Outbound contract split 2016-04-15 23:23:54 +01:00
Stephane Maldini 4431a76a05 Update addCookie signature and improve client cookie 2016-04-15 21:25:56 +01:00
Rossen Stoyanchev b2ca216498 Add RequestCondition hierarchy
A pretty complete equivalent to the same in spring-webmvc except for
CORS checks, and custom HTTP methods. Another notable difference is
that the "params" condition works on query params strictly.
2016-04-15 16:21:46 -04:00
Rossen Stoyanchev 641c6428e8 Add ContentTypeResolver strategy
A starting point for an alternative to the existing
ContentNegotiationStrategy but for use with ServerWebExchange.
2016-04-15 16:21:46 -04:00
Rossen Stoyanchev 09c5711862 Polish ServerHttpRequest
Consistent initialization of HttpHeaders and the cookies map.
 - allow sub-classes to create instance
 - make unmodifiable
2016-04-15 16:21:46 -04:00
Rossen Stoyanchev a7f32cd528 Add getQueryParams to ServerHttpRequest 2016-04-15 16:21:46 -04:00
Rossen Stoyanchev 61136e614e Fix issue with Cookies in ReactorServerHttpResponse 2016-04-15 16:20:55 -04:00
Stephane Maldini 4ddd9d2895 fix change issue on HttpChannel#writeHeaders to sendHeaders 2016-04-15 20:04:52 +01:00
Stephane Maldini 4a0adc2b2d Sync with reactor-netty and reactor-ipc 2016-04-15 19:55:33 +01:00
Rossen Stoyanchev 33a7b91e57 Add abstract case class HandlerMappings
This commit adds AbstractHandlerMethodMapping, a starting point for
AbstractHandlerMapping, and HttpRequestPathHelper with a similar
purpose to UrlPathHelper but based with ServerWebExchange as input.
2016-04-15 04:08:19 -04:00
Rossen Stoyanchev 341f23e0e6 Add "result" package under ~.web.reactive
The new package is parallel to the "mvc" package under spring-webmvc
and a place to hold the various programming model styles.
2016-04-14 16:15:44 -04:00
Rossen Stoyanchev 3460e577ad Polish "simple" handler support
- correct name of HttpHandlerHandlerAdapter to WebHandlerHandlerAdapter
- shorten SimpleHandlerResultHandler to SimpleResultHandler
- add HandlerResult constructor without Model
- update tests
2016-04-14 15:17:28 -04:00
Stephane Maldini ff6b639cf9 sync with dispatchOn change in reactor-core 2016-04-11 16:04:01 +01:00
Brian Clozel a3b371bf4b Accept all media types in StringDecodere
This commit adds the "*/*" media type in the list of compatible media
types for the StringDecoder. This allows this decoder to decoder
payloads of any media type as long as the target type is String.

Fixes #87
2016-04-08 22:18:46 +02:00
Stephane Maldini da2276a954 First wave scheduler contract migration 2016-04-08 03:09:32 +01:00
Sebastien Deleuze 87ce5d641c Update dependencies
- Spring Framework 4.2.3.RELEASE -> 4.3.0.RC1
 - Netty 4.1.0.CR3 -> 4.1.0.CR6
 - Jackson 2.6.2 -> 2.7.3
 - Jetty 9.3.5.v20151012 -> 9.3.8.v20160314
 - Undertow 1.3.5.Final -> 1.3.20.Final
2016-04-07 20:26:38 +02:00
Brian Clozel 023dafa903 Support "text/*" media types in StringDecoder 2016-04-07 16:06:56 +02:00
Brian Clozel e3f87b3e3a Polish 2016-04-07 16:06:56 +02:00
Brian Clozel 09327181c4 Improve ClientHttpRequestFactory javadoc
This commit underlines the fact that the request created by a
ClientHttpRequestFactory should be augmented with a message body using
the `ClientHttpRequest#setBody` method before it is executed.

See #82
2016-04-07 16:06:56 +02:00
Brian Clozel ddf996cfeb Polish HttpRequestBuilder API
This commit makes messageEncoders a required argument for building a
client request - those are needed to actually encode the body object as
a reactive stream to be written to the HTTP request body.

Removed raw types usage in DefaultHttpRequestBuilder.

DefaultHttpRequestBuilder now uses a UriTemplateHandler to expand URI
templates + variables into a concrete URI.

Fixes #80, fixes #85, fixes #86
2016-04-07 16:06:56 +02:00
Brian Clozel 8ed2925ce3 Propagate Errors in DefaultHttpRequestBuilder
This commit introduces the new `WebClientException` for wrapping
client-side exceptions.
This exception is now thrown when now message encoder can be found for
writing the request body as an HTTP request message.

Fixes #83
2016-04-07 16:06:56 +02:00
Brian Clozel e2a07659ab Add generics support for WebResponseExtractors
This commit adds generics support for WebResponseExtractors.
Types should be described using a ResolvableType, which can be
created with static methods like:

    // for the type Event<Registration>
    ResolvableType.forClassWithGenerics(Event.class, Registration.class)

Fixes #89
2016-04-07 16:06:56 +02:00
Sebastien Deleuze 24a63f1d90 Upgrade RxNetty to 0.5.2-SNAPSHOT and Tomcat to 8.0.33 2016-04-07 16:04:39 +02:00
Brian Clozel 04fae44163 Switch back to reactor-core SNAPSHOT versions
Some important issues have been fixed in recent SNAPSHOT versions.

See #78 and #70
2016-04-07 15:10:49 +02:00
Arjen Poutsma 5f09a62950 Merge pull request #77 from poutsma/refactor_jaxb2decoder
Improve Jaxb2Decoder
2016-04-06 16:25:36 +02:00
Arjen Poutsma 75399814cd Improve Jaxb2Decoder
- Introcuces XmlEventDecoder which decodes from DataBuffer to
  javax.xml.stream.events.XMLEvent. It uses the Aalto async XML API if
  available, but falls back to a blocking default if not.

- Refacors Jaxb2Decoder to use said XmlEventDecoder, and split the
  stream of events into separate substreams by using the JAXB annotation
  value, one stream for each part of the tree that can be unmarshaled to
  the given type.

- Various improvements in the JAXB code.
2016-04-06 16:22:49 +02:00
Arjen Poutsma a8f27af5fb Polishing. 2016-04-06 16:20:08 +02:00
Brian Clozel ef58fdcd7b Merge pull request #88 from rwinch/gh-81-requestpostprocessor
Add RequestPostProcessor
2016-04-04 11:28:43 +02:00
Mark Paluch 9e79b344ca Implement review feedback.
Remove empty string optimization. Simplify test to use only Mono/Flux/TestSubscriber instead of mixing with RxJava.
2016-04-04 09:49:22 +02:00
Rob Winch fd6fc30eea Add RequestPostProcessor
Fixes gh-81
2016-03-31 12:33:45 -05:00
Mark Paluch c4b9d94c33 Use CharsetDecoder to decode a DataBuffer into a String. 2016-03-31 16:39:39 +02:00
Arjen Poutsma 75d006d2f9 Improve StringDecoder. 2016-03-31 11:31:02 +02:00
Arjen Poutsma d927d72204 Merge pull request #76 from lukas-krecan/trivial-test-fix
Replacing potentionally slow and infinite while loop by a latch
2016-03-29 10:36:22 +02:00
Lukas Krecan 23f3fff367 Replacing potentionally slow and infinite while loop by a latch 2016-03-29 10:33:21 +02:00
Arjen Poutsma d9d76ecd19 Polishing 2016-03-24 09:39:58 +01:00
Arjen Poutsma 10af007110 Merge pull request #74 from poutsma/refactor_servlet31_undertow
Refactoring of Servlet 3.1 and Undertow support
2016-03-23 17:10:07 +01:00
Arjen Poutsma 35e511b03f Resolved comments from review
This commit resolves a few comments brought forward during a review
meeting, specifically:

- It renames AbstractResponseBodyPublisher to
  AbstractRequestBodyPublisher.
- It separates out registration logic into a register method.
- It moves the RequestBodyPublisher and ResponseBodySubscriber for the
  Servlet 3.1 support back into ServletHttpHandlerAdapter.
2016-03-23 17:04:18 +01:00
Arjen Poutsma d20b0003c6 Refactoring of Servlet 3.1 and Undertow support
- Introduce abstract base class for Servlet 3.1 and Undertow support
- Simplify Undertow support
2016-03-23 16:02:44 +01:00
Arjen Poutsma f7c6c69e51 Improve JacksonJsonEncoder
This commit removes the need for the custom Subscriber in
JsonObjectEncoder, and replaces it with higher-level Flux and Mono-based
solution.
2016-03-21 11:37:51 +01:00
Arjen Poutsma 7f786ce4d7 Added DataBufferAllocator property to ReactiveHttpOutputMessage, and use that to pass on to Encoder.encode(). 2016-03-18 16:14:33 +01:00
Arjen Poutsma 1836b2825b Added DataBufferAllocator parameter to Encoder.encode, and use that instead of AbstractAllocatingEncoder base class. 2016-03-18 16:05:30 +01:00
Arjen Poutsma e56dda1864 Make JsonObjectDecoder use allocator property on DataBuffer. 2016-03-18 14:11:25 +01:00
Arjen Poutsma b838fdab88 Added allocator property to DataBuffer 2016-03-18 12:16:23 +01:00
Arjen Poutsma 273c1b85e6 Reduced batch size to 1, so that we don't block on init. 2016-03-18 11:58:55 +01:00
Arjen Poutsma 2c52731417 Various test improvements 2016-03-18 10:02:28 +01:00
Arjen Poutsma 5519428d43 Replaced DataBufferPublisherInputStream with JDK equivalent. 2016-03-18 10:02:28 +01:00
Rossen Stoyanchev 72dbe9012e Add cookies to ClientHttpRequest/Response 2016-03-17 21:04:50 -04:00
Rossen Stoyanchev e19abf9c90 Rename ServerCookie to ResponseCookie
HttpCookie-ResponseCookie follows HttpEntity-ResponseEntity and also
avoids use of "Server" outside of server sub-package.
2016-03-17 15:28:55 -04:00
Arjen Poutsma a874aa4db9 Merge pull request #71 from rwinch/gradle-2.12
Update to Gradle 2.12
2016-03-17 16:17:09 +01:00
Rob Winch ececec21f7 Update to Gradle 2.12 2016-03-17 10:11:28 -05:00
Rob Winch 62753102dc Ensure a consistent netty version
Currently there are clashes between io.netty:netty-common:4.1.0.Beta7 and
io.netty:netty-all:4.1.0.CR3 which can cause errors in the build related
to "VerifyError: Bad type on operand stack".

One solution would be to exclude the jars that duplicate the classes.
However, this can be fragile since additional dependencies may be added
that bring in the dependency transitively.

This commit locks the version for any artifiact with the group "io.nettty"
to ensure the correct version of netty is used.
2016-03-17 10:11:12 -05:00
Arjen Poutsma 10a04b0769 Test improvements. 2016-03-17 10:21:04 +01:00
Stephane Maldini 530c817287 sync reactor-netty 2016-03-12 01:16:49 +00:00
Stephane Maldini 13ddfb4aab update package 2016-03-11 22:15:11 +00:00
Stephane Maldini f02492e15f sync with reactor-core and reactor-io 2016-03-11 20:02:34 +00:00
Rossen Stoyanchev e97a55ad54 WebClient supports Void response body
WebResponseExtractor uses Mono.when with the response status, headers,
and the decoded body. However when the response body stream is empty
then when completes empty too.

This change adds defaultIfEmpty handling for en empty response body.
2016-03-07 17:07:12 -05:00
Rossen Stoyanchev b2648f84ad DefaultWebSessionManager supports multiple sessions
Issue: #64
2016-03-07 11:20:51 -05:00
Stephane Maldini 1eadee5655 integration build with Reactor Core 2.5.0.M2 2016-03-07 13:57:27 +00:00
Rossen Stoyanchev ca7aeaae35 WebSessionIdResolver now returns List of ids
Issue: #64
2016-03-03 22:32:03 -05:00
Rossen Stoyanchev dbc6478b8a Refactor HTTP Cookie support
There is now an HttpCookie (simple name-value pair) and separately a
ServerHttpCookie sub-class with additional attributes that a server
can send to clients.

HttpHeaders is no longer the place to access cookies. Instead there is
a read-only HttpCookie map on ServerHttpRequest and a mutable
ServerHttpCookie map on ServerHttpResponse.

Cookies are stored in a map that preserves their order.
2016-03-03 22:17:39 -05:00
Stephane Maldini a8c777b35f Remove reference to Fluxion 2016-03-04 00:05:35 +00:00
Stephane Maldini ce4a687cf2 remove reactor-stream and related artefacts, update tests 2016-03-03 23:57:03 +00:00
Sebastien Deleuze 379ce6354e Update for latest Reactor Core Snapshot 2016-03-01 22:19:54 +01:00
Sebastien Deleuze dc52d4c31f Update for latest Reactor Core Snapshot 2016-03-01 22:07:54 +01:00
Stephane Maldini 14948d4241 sync reactor 2016-03-01 20:50:55 +00:00
Stephane Maldini 4197f002d8 Arrange WriteWithOperator to save some allocation cost with the same technique used by RSC and Reactor 2016-02-28 11:49:00 +00:00
Stephane Maldini 423a4852c5 use EmptySubscription 2016-02-28 11:29:46 +00:00
Stephane Maldini fc1b2e96f7 Introduce Mono#justOrEmpty(T) 2016-02-28 00:56:10 +00:00
Stephane Maldini 999dfe3925 Sync BaseSubscriber 2016-02-27 23:18:22 +00:00
Stephane Maldini 24d9e99de1 Sync toCompletableFuture 2016-02-27 21:36:31 +00:00
Stephane Maldini cc77a338b1 Sync reactor-core jdk8 bump 2016-02-27 13:34:15 +00:00
Stephane Maldini 4c477189a6 revert module Reactor Fluxion to Reactor Stream 2016-02-27 11:06:07 +00:00
Stephane Maldini 9f94f8c88e Sync to Fluxion to remove Stream confusion 2016-02-26 21:42:52 +00:00
Arjen Poutsma 361707c448 Servlet 3.1 support cleanup
Claneup of the Servlet 3.1 support:

 - moved RequestBodyPublisher to ServletServerHttpRequest
 - moved ResponseBodySubscribera to ServletServerHttpResponse
 - response body is now copied to ServletOutputStream in chunks, rather
   than one big byte[]
2016-02-23 14:35:49 +01:00
Arjen Poutsma 2fcbeb6595 Fixed issue with DefaultDataBuffer.asInputStream() 2016-02-23 14:14:34 +01:00
Stephane Maldini f920d2ce1e sync with reactor-stream update 2016-02-23 09:39:49 +00:00
Arjen Poutsma 51a90465d4 Polishing 2016-02-23 10:24:18 +01:00
Arjen Poutsma f036f745a6 Improved RxNetty support. 2016-02-18 15:49:45 +01:00
Brian Clozel d68ff29e9b Use default buffer allocator in RequestMappingHandlerAdapter
This commit removes RequestMappingHandlerAdapter's hard dependency on
Netty by switching to the DefaultDataBufferAllocator.
2016-02-10 23:16:48 +01:00
Sebastien Deleuze 628ae2fda8 Use Flux instead of Stream in Publisher based integration tests 2016-02-09 18:02:02 +01:00
Sebastien Deleuze 36788207f3 Polish RequestMappingIntegrationTests 2016-02-09 17:53:26 +01:00
Rossen Stoyanchev 3ca1d33905 Merge templating branch 2016-02-08 18:14:42 -05:00
Rossen Stoyanchev 971ca6beb8 Add HTML rendering integration test 2016-02-08 18:13:42 -05:00
Rossen Stoyanchev 29db80c3e8 Add FreeMarker View, ViewResolver and basic hierarchy 2016-02-08 18:13:42 -05:00
Rossen Stoyanchev 55d37c0522 Add View, ViewResolver, and ViewResolverResultHandler
This commit adds a View and ViewResolver contracts to support HTML
template based rendering.

ViewResolverResultHandler applies view resolution by iterating the
resolvers to resolve to a view and then use it to render.
2016-02-08 18:13:37 -05:00
Rossen Stoyanchev 14997eccf3 Support Model as method argument and in HandlerResult
A model is created and passed to argument resolvers including a new
ModelArgumentResolver. The model is then exposed for result handling
as a field in HandlerResult.
2016-02-08 18:04:07 -05:00
Rossen Stoyanchev e92174c772 Update HandlerResult
Rename result to returnValue and resultType to returnValueType to
reflect what they represent.

The returnValue getter is also wrapped as Optional since the value
returned from a handler may be null (e.g. void method, null value).
2016-02-07 21:50:56 -05:00
Stephane Maldini b7b423a003 Remove Stream#toBlockingQueue use 2016-02-08 00:25:52 +00:00
Arjen Poutsma 4a24979181 Various DataBuffer utility enhancements
- Javadoc for DataBufferUtils
 - Introduction of DataBufferTestUtils, containing methods for dumping
   the entire contents of a buffer
2016-02-05 14:31:48 +01:00
Stephane Maldini 52292cafae sync reactor-core scheduler 2016-02-04 03:08:26 +00:00
Brian Clozel 7ab92cfccf Add WebResponseExtractor impl for RxJava1
This commit adds `RxJava1WebResponseExtractors`, a static factory of
`WebResponseExtractor`s that are based on the RxJava1 composition API.
All extracted types are based on the `Single` and `Observable` types.
2016-02-02 14:06:02 +01:00
Brian Clozel 69ce33e1ee Add WebClient and its WebResponseExtractor API
This commit adds the `WebClient`, which relies on several parts of our
infrastructure:
* a `ClientHttpRequestFactory` to drive the underlying client library
* a `HttpRequestBuilder` builder API to create the client request
* a `WebResponseExtractor` to extract the "low-level"
`ClientHttpResponse` into a higher level representation such as a
decoded body

The `WebResponseExtractors` helper class contains many extractor
implementations all based on the `Flux`/`Mono` composition API.
2016-02-02 14:06:02 +01:00
Brian Clozel f63960af0a Add client Request/Response impl. for RxNetty
This commit adds the `ClientHttpRequest` and `ClientHttpResponse`
implementations for the RxNetty HTTP client.
This client library is based on the `Single` and `Observable`
composition API, so this has to be converted to the `Flux`/`Mono`
variants.
2016-02-02 14:06:01 +01:00
Brian Clozel 255d2de553 Add client Request/Response impl. for Reactor-Net
This commit introduces the `ClientHttpRequest` and `ClientHttpResponse`
implementations for the Reactor-Net HTTP client. This client is already
based on the `Flux` and `Mono` contracts.

This commit also adds a `AbstractClientHttpRequest` to support the
`ClientHttpRequest` implementations; it mirrors the
`AbstractServerHttpResponse` contract with a `beforeCommit` to register
`Supplier`s that should be notified before the request is committed.
2016-02-02 14:06:01 +01:00
Brian Clozel a6469baa4f Add HttpRequestBuilder default implementation
This commit adds a `DefaultHttpRequestBuilder` and its companion static
builders in `HttpRequestBuilders`. This allows to build client requests
with a friendly builder API, inspired by Spring's MockMvc API.
2016-02-02 14:06:01 +01:00
Brian Clozel 0983d302c7 Add base contracts for the Web client
This commit adds the base contracts for the Web client.
The "Reactive" prefixes of the previously commited contracts has been
removed to match the server ones.

Both the `ClientHttpRequest` and the `ServerHttpResponse` extend
`ReactiveHttpOutputMessage`, which now has a `beforeCommit` method,
necessary in both client and server implementations.

`HttpRequestBuilder` will be used by the developers to create requests
with a nice builder API. `ClientHttpRequestFactory` will provide support
for many HTTP client libraries in this new client.
2016-02-02 14:06:01 +01:00
Arjen Poutsma a4be950e37 Polishing 2016-02-02 13:57:02 +01:00
Stephane Maldini 199252cda6 sync 2016-01-28 20:57:24 +00:00
Stephane Maldini 44f4930e29 sync 2016-01-28 20:36:29 +00:00
Stephane Maldini 9204fdc371 fix timer issues
sync reactor-core
2016-01-28 18:59:56 +00:00
Stephane Maldini 28dcf2e78f fix compile test issue 2016-01-28 18:29:54 +00:00
Sebastien Deleuze ee9c5833f5 Update our tests to use TestSubscriber 2016-01-28 10:24:05 +01:00
Rossen Stoyanchev b9f4698b69 Remove license from package infos 2016-01-27 17:45:54 -05:00
Rossen Stoyanchev 381855aaf3 Refine names in web.server and polish Javadoc
WebServerExchange -> ServerWebExchange

Follows the same convention as in the http package also better allowing
the possibility for a client equivalent in the future.

WebToHttpHandlerBuilder -> WebHttpHandlerBuilder
WebToHttpHandlerAdapter -> WebHttpHandlerAdapter

More consistent with Spring conventions.
2016-01-27 17:05:07 -05:00
Rossen Stoyanchev e59b927fd1 Refine web.server package structure
Introduce adapter and handler sub-packages under web.server following a
review prompted by the addition of the session package and the package
cycle it brought in based on dependency on session.WebSessionManager.
2016-01-27 16:26:47 -05:00
Rossen Stoyanchev 407d11a58a Server-side session support
This commit adds initial support for a maintaining a server-side
session with attributes across HTTP requests. The WebSession
abstraction can be accessed via WebServerExchange from a WebFilter or
the target WebHandler.

The session sub-package contains additional abstractions for creating
and managing sessions providing a basis for extensibility (e.g. Spring
Session). Those include WebSessionManager, SessionIdStrategy, and
SessionStore along with a cookie-based session id strategy and an
in-memory session store in use by default.

Note that the current API does not provide a way to invalidate or
re-create the session from server side code.
2016-01-27 16:24:20 -05:00
Rossen Stoyanchev 3744549a3e Add setComplete + beforeCommit to ServerHttpResponse
setComplete replaces writeHeaders as a more general lifecycle method
to perform any kind of handling at the end of request processing, for
example to ensure headers are written if not already.

beforeCommit provides an extension point for an action to be invoked
just before the response is committed, e.g. adding headers/cookies.
2016-01-27 16:24:20 -05:00
Stephane Maldini 03e6d7dabf minor sync 2016-01-27 20:49:18 +00:00
Stephane Maldini 8a6fa02887 Sync with RSC move graph to flow 2016-01-27 17:42:05 +00:00
Sebastien Deleuze dc91c81fc4 Polishing 2016-01-27 17:04:08 +01:00
Sebastien Deleuze 506c4bc27b Finish to cleanup Reactor Buffer usages
We use it only for Reactor Net support now.
2016-01-27 17:01:17 +01:00
Arjen Poutsma 1c7d845245 Merge pull request #63 from poutsma/byte_buffer_abstraction
Byte buffer abstraction
2016-01-27 16:17:04 +01:00
Arjen Poutsma c84ef6cbf3 Incorporated misc. suggestions from the PR. 2016-01-27 16:07:02 +01:00
Arjen Poutsma 66c424daf9 Removed DataBufferAllocator.allocateHeapBuffer and allocateDirectBuffer in favor of allocateBuffer. 2016-01-27 16:04:03 +01:00
Arjen Poutsma b8f2388d60 Removed unused classes 2016-01-27 16:04:03 +01:00
Arjen Poutsma 225179bc6f Updated http and web packages to use DataBuffer 2016-01-27 16:04:03 +01:00
Arjen Poutsma 2981b5e6e8 Updated Encoder and Decoder to use DataBuffer 2016-01-27 16:04:03 +01:00
Arjen Poutsma 38ab47f8a0 Added DataBuffer abstraction
Added DataBuffer and DataBufferAllocator, and provided a default NIO
ByteBuffer-based implementation of those, as well as a Netty
ByteBuf-based version.
2016-01-27 16:04:03 +01:00
Stephane Maldini 641a57ec93 no need to convert to array list with last zip signature 2016-01-27 14:59:19 +00:00
Stephane Maldini 10f4f64e6f sync updates with mono 2016-01-26 23:15:55 +00:00
Arjen Poutsma 21fff02dbd Fixing the build that bad boy @smaldini broke 2016-01-26 12:43:59 +01:00
Stephane Maldini ac94bf1120 sync with reactor-stream package-scope change 2016-01-25 09:05:40 +00:00
Stephane Maldini a907898910 fix signature 2016-01-22 23:11:31 +00:00
Stephane Maldini 0ba5e1d21c sync update on reactor-io Buffer move 2016-01-21 11:59:59 +00:00
Rossen Stoyanchev 30b007dc26 Based on fix in core for SPR-13876 2016-01-20 18:01:32 -05:00
Stephane Maldini 4e162122af sync update on reactor-core 2016-01-20 20:50:28 +00:00
Stephane Maldini 7b3e9e0950 move queue.disruptor and packagescope RingBufferUtils/RequestTask 2016-01-20 18:01:07 +00:00
Sebastien Deleuze 4572cfa38c Fix RxJava1Converter -> RxJava1ObservableConverter 2016-01-20 11:45:18 +01:00
Rossen Stoyanchev 2dd9c92267 Update reactor converter package 2016-01-19 21:34:28 -05:00
Stephane Maldini 198e316412 demote cyclic dependency under reactor-core reactor package
-> reactor.Mono : reactor.core.publisher.Mono
-> reactor.Flux : reactor.core.publisher.Flux
-> reactor.Processors : reactor.core.publisher.Processors
-> reactor.Timers : reactor.core.timer.Timers
-> reactor.Subscribers : reactor.core.subscriber.Subscribers
2016-01-19 20:18:47 +00:00
Stephane Maldini 53b76e90fc move BackpressureUtils to subscription 2016-01-19 19:57:34 +00:00
Stephane Maldini bdfdd64db7 merge core.processor and core.publisher 2016-01-19 19:46:46 +00:00
Stephane Maldini 386dfb0881 update DependencyUtils package 2016-01-19 19:30:20 +00:00
Sebastien Deleuze de300e8c00 Fix the Javadoc external links by using a page without frames 2016-01-14 20:01:38 +01:00
Sebastien Deleuze 9436dd7412 Polish Javadoc 2016-01-14 19:18:38 +01:00
Sebastien Deleuze 398eb0b478 Polish packages documentation 2016-01-14 18:54:17 +01:00
Sebastien Deleuze ae6912086a Add packages documentation 2016-01-14 18:45:43 +01:00
Sebastien Deleuze 2cdce62c3d Update README with the Javadoc link 2016-01-14 16:15:34 +01:00
Sebastien Deleuze 14cb20a9f1 Disable uniqueVersion in order to get a reliable Javadoc link 2016-01-14 16:12:27 +01:00
Sebastien Deleuze 22bea1da01 Add sources and Javadoc to the build 2016-01-14 15:38:35 +01:00
Stephane Maldini 89da87a3e5 Async test case to explore jetty/tomcat issues 2016-01-14 12:38:21 +00:00
Sebastien Deleuze 72e5aa39ec Polish @RestController support 2016-01-14 11:06:04 +01:00
Stephane Maldini 1e28dee608 add streaming test, commented due to issue with a tomcat and jetty 2016-01-14 03:59:15 +00:00
Stephane Maldini 0f432f735a use reactor cookie support 2016-01-14 03:34:25 +00:00
Rossen Stoyanchev da90f03f4c Support type-level @ResponeBody (and @RestController) 2016-01-13 18:12:36 -05:00
Rossen Stoyanchev 437c127b62 Log and handle unresolved exceptions
Before this change use of ExceptionHandlingWebHandler did ensure no
error signals are allowed to escape (hence relying on runtime
behavior).

This change ensures the same is done even when
ExceptionHandlingWebHandler is not configured for use, at the lowest
level which is the WebToHttpHandlerAdapter.
2016-01-13 18:06:42 -05:00
Brian Clozel cf6ceeed62 Allow Splitting/aggregation operations in Decoders
When decoding buffers as plain strings, the StringDecoder returns a
Publisher that may produce one or more `onNext` events.
This is perfectly valid, but leads to errors when trying to convert the
resulting Publisher into a `reactor.Mono` or `rx.Single`.

If the original Publisher emits 2 or more `onNext` signals,
converting to:
* `rx.Single` will throw an error saying that the underlying Observable
"emitted too many elements"
* `reactor.Mono` may contain only the first emitted element

This commit adds a `AbstractRawByteStreamDecoder` that takes a
`SubscriberBarrier` to apply splitting/aggregation operations on the
received elements.
The `StringDecoder` class now inherits from this abstract class and
uses one of the provided `SubscriberBarrier` implementations to
buffer all received elements in a single buffer.
2016-01-13 12:23:47 +01:00
Sebastien Deleuze 99e51a9101 Replace Reactor Stream by Flux in tests when possible 2016-01-12 15:27:02 +01:00
Sebastien Deleuze d9b67f5e72 Use Mono semantics for JSON object/array serialization
Before this commit, a handler method returning a stream with a JSON
content-type was producing a JSON object for single element streams
or a JSON array for multiple elements streams.

This kind of dynamic change of the output based on the number of
elements was difficult to handle on client side and not consistent
with Spring MVC behavior.

With this commit, we achieve a more consistent behavior by using
the Mono semantics to control this behavior. Mono (and Promise/Single)
are serialized to JSON object and Flux (and Observable/Stream) are
serialized to JSON array.
2016-01-12 11:31:18 +01:00
Rossen Stoyanchev c3cde84e6b Polish cookie support
HttpCookie is now immutable with factory methods to create a client
cookie (name-value) vs a server cookie (name-value + attributes)
including a builder for the latter.
2016-01-11 22:54:46 -05:00
Sebastien Deleuze ae4b35ced7 Add Mono and Flux support in @RequestMapping handler methods 2016-01-11 13:02:36 +01:00
Rossen Stoyanchev 1faeb0ec87 Add HttpCookie + server support through HttpHeaders 2016-01-10 22:36:45 -05:00
Rossen Stoyanchev f8ef2e0220 Add base classes for ServerHttpRequest/Response impls 2016-01-10 15:46:56 -05:00
Rossen Stoyanchev eedc90818f Re-introduce writeHeaders() in ServerHttpResponse
This commit brings back the writeHeaders method on ServerHttpResponse
that was once added (2a6a4f) and then removed (9c7151).

This version is a little simpler since writeHeaders doesn't explicitly
flush/send headers which runtimes are expected to do by default.
Instead the main purpose of writeHeaders now is to ensure changes made
via HttpHeaders are applied to the underlying runtime response at some
point and we now do that once at the very end.

This approach provides the most flexibility (vs keeping HttpHeaders in
sync) because it allows a full and consistent set of mutative
operations for both headers and cookies (to be added) regardless of the
API exposed by the underlying runtime.
2016-01-10 06:25:12 -05:00
Rossen Stoyanchev 4f614fa0fd Add WebServerExchange
This change adds a WebServerExchange and updates all contracts at the
the same level (i.e. org.springframework.web.server) as well as the
org.springframework.web.reactive level to use it so that all
framework-related code will have access to server-side processing
features such as request attributes (and others to come).
2016-01-08 12:30:13 -05:00
Rossen Stoyanchev 54e4e012b2 Separate out web.server from http.server.reactive
This change separates out lower-level HTTP adapter code from the more
(framework-specific) HTTP processing into a separate package under
org.springframework.web.server (not under org.springframework.http).
2016-01-08 12:29:04 -05:00
Stephane Maldini 94be412327 Remove last Stream reference 2016-01-07 23:41:48 +00:00
Stephane Maldini b4c3a67d2c Use Stream instead of Streams and uncomment reactor test 2016-01-07 23:29:16 +00:00
Rossen Stoyanchev 97af9998d5 Refine exception handling
Refine exception handling responsibilities between the
DispatcherHandler and the HandlerAdapter.
2016-01-07 18:26:27 -05:00
Stephane Maldini 70b8848492 fix Streams to Stream in test 2016-01-07 22:28:35 +00:00
Rossen Stoyanchev 9a1492e401 Polish 2016-01-07 17:09:49 -05:00
Rossen Stoyanchev a712f43654 Polish 2016-01-07 15:26:11 -05:00
Rossen Stoyanchev c3a8bf4d17 Revert "Remove mandatory dependency on Reactor Stream"
This reverts commit d5e6f70483d4a6c8af3cc5e97e52a54e98199169.
2016-01-07 15:23:55 -05:00
Sebastien Deleuze 318092cfd0 Use Mono#defaultIfEmpty instead of Flux#defaultIfEmpty 2016-01-07 15:58:46 +01:00
Sebastien Deleuze 327c420409 Remove mandatory dependency on Reactor Stream with JarJar 2016-01-07 14:51:43 +01:00
Sebastien Deleuze 8ef7e2ff77 Use Reactor 2.5 Flux and Mono Rx light API
Flux and Mono are used both for implementation and exposed at API
level to express 1 versus N semantic and to provide default Rx
operators:
- Flux<T> for multiple values Publisher (issue #48)
- Mono<T> for single value Publisher (issue #50)
- Mono<Void> for Publisher with no value (issue #49)
2016-01-07 11:14:12 +01:00
Rossen Stoyanchev 8ef2ce44f4 Temporarily remove Reactor from integration tests
https://github.com/spring-projects/spring-reactive/issues/57
2015-12-31 13:18:13 -05:00
Rossen Stoyanchev 0aade73c88 Update Servlet + Undertow req & resp implementations
For those runtimes that don't directly support Reacitve Streams this
commit separates more formally Reactive Streams bridge code out of
the request and response implementations which become simple adapters
to the ServerHttpRequest/Response contracts like their RxNetty and
Reactor Net counterparts.
2015-12-31 12:55:09 -05:00
Rossen Stoyanchev 869f6bef40 Polish server request & response implementations 2015-12-31 12:27:40 -05:00
Rossen Stoyanchev 6b05d17248 Response headers always in sync with native response
ServerHttpResponse implementations now immediately propagate
HttpHeaders changes as they so there is no need to call applyHeaders().

The writeHeaders from ServerHttpResponse is also removed. RxNetty and
Reactor Net both support implicitly completing if the handler
completes without explicitly writing the headers or the response body.
2015-12-29 23:13:21 -05:00
Rossen Stoyanchev 34eb6d5426 Add support for @ExceptionHandler methods 2015-12-29 23:13:21 -05:00
Rossen Stoyanchev 8c89b478d9 Add operator for deferred writes 2015-12-29 23:13:21 -05:00
Rossen Stoyanchev 9789db23d2 Rename HandlerResult fields from value to result 2015-12-29 23:13:21 -05:00
Rossen Stoyanchev 84e3ad342b Remove @Ignore from 404 status code tests 2015-12-29 23:13:21 -05:00
Rossen Stoyanchev 9eb07b7780 Update package for reactor Signal 2015-12-29 23:13:21 -05:00
Rossen Stoyanchev a12c172ceb Switch to rxnetty-http dependency
The "rxnetty" artifact is old (October 2015). There is now rxnetty-http
and other modules that have more recent snapshots (December 2015).
2015-12-29 23:13:21 -05:00
Stephane Maldini da4e4aab39 test operator log 2015-12-18 16:56:17 +00:00
Stephane Maldini 15185c75a3 use Publishers.onErrorResumeNext 2015-12-17 13:34:09 +00:00
Rossen Stoyanchev 69973d984d Fix test failure 2015-12-16 12:30:15 -05:00
Rossen Stoyanchev 623874b4d0 Constant HandlerNotFoundException 2015-12-16 11:08:41 -05:00
Rossen Stoyanchev 1b3289d0d5 Add InternalServerErrorExceptionHandler 2015-12-15 17:04:53 -05:00
Rossen Stoyanchev f2cd92a243 Fix imports 2015-12-15 12:09:23 -05:00
Rossen Stoyanchev c13a8c9bb4 DispatcherHandler maps errors to ResponseStatusException
The DispatcherHandler now has an errorMapper property that is a
function for transforming errors. By default this property is set to an
instance of DispatcherHandlerExceptionMapper which wraps "standard"
framework exceptions and @ResponseStatus-annotated exceptions as
ResponseStatusException.

This makes it easy to handle the exceptions downstream uniformly.
2015-12-15 12:08:13 -05:00
Rossen Stoyanchev 1f15b7e074 Add ResponseStatusException
This change adds a ResponseStatusException to associate an exception
with a status code at runtime. Along with that is an
ResponseStatusExceptionHandler that handles ResponseStatusException
by setting the response status.
2015-12-15 12:06:53 -05:00
Rossen Stoyanchev 5231e7da7b Fix failing test 2015-12-10 16:50:28 -05:00
Rossen Stoyanchev a0018d13e1 Add DispatcherHandlerErrorTests
The tests demonstrate failures at various phases of request processing
and the resulting error signals.
2015-12-10 16:35:40 -05:00
Rossen Stoyanchev 4ba3d0736f Add HttpExceptionHandler 2015-12-10 16:35:40 -05:00
Rossen Stoyanchev 448aac813a Add MockServerHttpRequest/Response 2015-12-10 16:35:40 -05:00
Sebastien Deleuze 78454f5a2e Add a link to Spring Reactive Playground 2015-12-09 11:18:50 +01:00
Rossen Stoyanchev ef3560a55a Add HttpHandlerDecorator and fix test package 2015-12-08 22:50:25 -05:00
Rossen Stoyanchev 1dcaff8a5c Updates to Javadoc 2015-12-08 22:50:24 -05:00
Stephane Maldini fbb0c702c9 minor reactor server impl to fulfill core introspection 2015-12-09 01:58:53 +00:00
Rossen Stoyanchev ad4be9462b Drop use of WebApplicationContext in tests
It brings along Servlet imports.
2015-12-08 14:33:23 -05:00
Stephane Maldini 4616938525 Prepare for a future change to downstream() inner method in reactor-core 2015-12-08 13:21:35 +00:00
Rossen Stoyanchev 45706422dd InvocableHandlerMethod and arg resolution updates
General improvements e.g. make use of Java 8 Stream. The main reason
for the refactoring however to tighten error handling. To that extent:

InvocableHandlerMethod turns all exceptions into Reactive Streams
error signals, in effect never allowing any Exceptions to bubble up.

HandlerMethodArgumentResolver may throw an Exception for sync resolution
or produce an error signal via the returned Publisher. Either way the
exception is consistently wrapped with helpful method argument details.
For the latter case using a custom mapError operator.

HandlerMethodArgumentResolver no longer needs to return Optional for
nullable argument values. Instead (for now) the defaultIfEmpty operator
of reactor.rx.Stream operator is used to ensure a default constant value
(called "NO_VALUE") is produced. That way an argument resolver may
produce 0..1 values where 0 means it did not resolve to any value and
that results in null passed as the argument value.

If a HandlerMethodArgumentResolver produces more than one value, all
additional values beyond the first one will be ignored with the help
of a custom "first" operator.

As HandlerMethod is invoked within the map operator, checked exceptions
are not allowed but instead of wrapping it in a runtime exception what
we really need is to unwrap the target exception for exception
resolution purposes. To this end concatMap is used to produce a nested
Publisher or an error Publisher with the unwrapped target exception.

Related to that InvocableHandlerMethod now returns
Publisher<HandlerResult> instead of Publisher<Object> so that no longer
needs to be externally mapped from Object to HandlerResult.

InvocableHandlerMethodTests provides tests for the above scenarios and
verifies the details of resulting error signals.
2015-12-07 17:36:58 -05:00
Sebastien Deleuze ce0bd2efc2 Improve Gradle dependencies version management
This commit also updates to the following dependencies:
 - Spring Framework 4.2.3.RELEASE
 - RxJava 1.1.0
2015-12-07 11:35:00 +01:00
Rossen Stoyanchev da98becf72 Move http.server to http.server.reactive 2015-12-02 17:46:07 -05:00
Rossen Stoyanchev 382c98f968 Remove isolated use of Reactor Buffer 2015-12-01 18:19:14 -05:00
Rossen Stoyanchev df80ffbf28 Spring-consistent naming in server.http package
This change also removes reactor-stream variants of the request and
response since the request and response aren't used directly by
application code and get passed through reactor.Publishers anyway.
2015-12-01 18:09:53 -05:00
Stephane Maldini b9a52d5f7c Change to Definitive generic signature for Publishers.zip 2015-12-01 16:51:52 +00:00
Stephane Maldini 9ce5c7416b compiler issue ? 2015-12-01 15:01:34 +00:00
Rossen Stoyanchev 71d1d11fac Non-blocking HandlerMapping chain 2015-12-01 07:34:35 -05:00
Stephane Maldini b26e746120 Use Publishers.zip instead of Streams.zip 2015-12-01 10:43:41 +00:00
Sebastien Deleuze 91c2b7afad Support handler methods returning void, Observable<Void>, etc. 2015-11-30 15:35:58 +01:00
Rossen Stoyanchev 57dc8199fb Add ReactiveHttpFilter 2015-11-25 13:11:01 -05:00
Sebastien Deleuze 0f8a4bf706 Polish imports 2015-11-25 10:42:23 +01:00
Sebastien Deleuze b18919d111 Improve Javadoc for HandlerAdapter and HandlerMapping 2015-11-25 10:35:09 +01:00
Rossen Stoyanchev d319edba28 HandlerMapping is now asynchronous 2015-11-24 17:36:44 -05:00
Sebastien Deleuze dc57e2621c Move HttpServer related classes back to src/main/java
This is needed in order to be able to use Spring Reactive in standalone
applications. These are temporary classes that will return in
src/test/java when Spring Boot support for Reactive applications will
be implemented.
2015-11-24 18:11:44 +01:00
Rossen Stoyanchev 4a3c0bc3b6 Remove top-level org.springfamework.reactive package
reactive.codec -> core.codec
reactive.io    -> util

These may very well not be the final locations. For now they simply
express that there are classes that belong somewhere in core, i.e.
they are lower level dependencies than web.
2015-11-22 15:02:18 -05:00
Rossen Stoyanchev 911d376922 Improve MimeType -> MediaType handling
This change adds an Encoder-to-MediaType lookup in
ResponseBodyResultHandler to avoid MimeType to MediaType creation at
runtime.
2015-11-22 14:41:59 -05:00
Rossen Stoyanchev 8d30722f21 Remove @MVC test with multiple matches
RequestMappingHandlerMapping currently picks the first match and does
have logic to deal with selecting the best match. This caused a
random test failure depending on which controller method was matched
first. This change removes the test.
2015-11-20 13:17:10 -05:00
Rossen Stoyanchev e9e4bcdc59 Move ~.web.reactive.server to ~.http.server 2015-11-20 13:10:44 -05:00
Rossen Stoyanchev 81867fa423 Refactor package structure for web
The web related code is now under org.springframework.web.reactive.
This is parallel to org.springframework.web (the top-level package of
spring-webmvc).
2015-11-13 17:49:31 -05:00
Rossen Stoyanchev 54ce20a5e0 Rename field in HandlerResult 2015-11-13 17:23:00 -05:00
Sebastien Deleuze c6713c23e3 Add a ResolvableType field to HandlerResult
This change allows to be able to check generic type on the return value
at HandlerAdapter and ResultHandler level. For example, it allows to do
a Publisher<Void> check in SimpleHandlerResultHandler.
2015-11-13 17:09:02 -05:00
Rossen Stoyanchev 5d4201d500 Fix "Content-Type" and "Accept" header processing
"Content-Type" is just a single MediaType.

For the response, the MediaType must be fully selected before
selecting and encoder.

The ResponseBodyResultHandler now includes actual content negotiation
with a potential 406 response.
2015-11-13 16:47:52 -05:00
Rossen Stoyanchev 2de127ad4a Polish 2015-11-13 15:55:50 -05:00
Sebastien Deleuze bdc5b38cb1 Refactor codecs
This commit introduces the following changes:
 - MessageToByteEncoder/Decoder renamed to Encoder/Decoder
 - JsonObjectEncoder/Decoder are now used directly in
   JacksonJsonEncoder/Decoder
 - Codec uses MimeType instead of MediaType since they
   are not specific to HTTP
 - Default MimeType are now managed thanks to
   Encoder/Decoder#getSupportedMimeTypes()
 - AbstractEncoder/Decoder takes care of generic MimeType related behavior
2015-11-13 15:01:02 -05:00
Rossen Stoyanchev 141d75791d Polish 2015-11-12 11:52:06 -05:00
Marek Hawrylczak f1bec5f1e4 referencing fields of a class using this 2015-11-07 16:37:40 +01:00
Marek Hawrylczak 9126fd9dec Indentation using tabs 2015-11-07 16:02:09 +01:00
Marek Hawrylczak 4c84117155 undertow support using non-blocking API’s 2015-11-07 15:52:47 +01:00
Rossen Stoyanchev a48c9b6305 Replace DefaultConversionService in spring-reactive 2015-10-30 17:58:59 -04:00
Rossen Stoyanchev c0dff3d2bb Comply with Spring Framework code style
https://github.com/spring-projects/spring-framework/wiki/Spring-Framework-Code-Style
2015-10-30 17:22:19 -04:00
Rossen Stoyanchev 0989c8b3c2 HandlerMethodArgumentResolver is now asynchronous 2015-10-30 16:04:49 -04:00
Rossen Stoyanchev 6b73993a38 HandlerAdapter is asynchronous again 2015-10-30 15:02:54 -04:00
Sebastien Deleuze 01ae961820 Make DefaultConversionService usable by the upcoming client 2015-10-30 11:03:49 +01:00
Sebastien Deleuze a257a4a37d Polishing 2015-10-30 11:02:40 +01:00
Arjen Poutsma b2bf18dd3d Removed Closeable implementation 2015-10-30 09:39:46 +01:00
Arjen Poutsma 5f2e958fae Removed IOException declaration 2015-10-30 09:38:29 +01:00
Arjen Poutsma 174e1d295d Merge pull request #36 from poutsma/httpmessage_hierarchy
Introduce HttpMessage hierarchy
2015-10-30 09:27:52 +01:00
Arjen Poutsma bd472af37e Updated Copyright notices 2015-10-30 09:26:34 +01:00
Arjen Poutsma 6006fa6ec2 Optimized imports 2015-10-30 09:24:53 +01:00
Arjen Poutsma e121f7ecd4 Improved documentation on setBody() 2015-10-29 16:44:13 +01:00
Arjen Poutsma 45a88974bc Changed addBody() to setBody() 2015-10-29 16:28:22 +01:00
Arjen Poutsma 5727abc82d Resolved merge conflicts 2015-10-29 16:08:10 +01:00
Arjen Poutsma bab3b6fd1c Introduce HttpMessage hierarchy
This commit introduces "reactive" sub-interfaces of the HttpMessage
interface found in the Spring Framework.
2015-10-29 15:45:28 +01:00
Stephane Maldini 3864fc24ff Fix JSON encoding issue 2015-10-29 11:10:38 +01:00
Stephane Maldini fd52ae999b Update to latest reactor-net
Latest reactor-net doesn't depend on reactor-stream anymore (neither reactor-codec and reactor-bus, it only depends on reactor-core).
2015-10-29 11:10:19 +01:00
Sebastien Deleuze adc50bbfb9 Add handler method parameter and result converters
This commit introduces the following changes:
 - Publisher -> Observable/Stream/etc. conversion is now managed
    in a dedicated ConversionService instead of directly in
    RequestBodyArgumentResolver and ResponseBodyResultHandler
 - More isolated logic that decides if the stream should be
    serialized as a JSON array or not
 - Publisher<ByteBuffer> are now handled by regular
   ByteBufferEncoder and ByteBufferDecoder
 - Handle Publisher<Void> return value properly
 - Ensure that the headers are properly written even for response
   without body
 - Improve JsonObjectEncoder to autodetect JSON arrays
2015-10-29 10:50:06 +01:00
Sebastien Deleuze cf2c1514af Use latest Reactor core capabilities
No need for rxjava-reactive-streams dependency and
 CompletableFutureUtils anymore.
2015-10-19 11:15:03 +02:00
Sebastien Deleuze cb09e58a82 Fix SimpleHandlerResultHandler by using Publishers.completable() 2015-10-19 11:01:24 +02:00
Sebastien Deleuze 3ad765556d Polish ByteBufferPublisherInputStream exception handling 2015-10-16 15:35:16 +02:00
Sebastien Deleuze 8ca04b8425 More accurate ResponseBodyResultHandler error message 2015-10-16 09:13:44 +02:00
Stephane Maldini 06a1ddbe93 Eliminate need for reactor stream in CompletableFutureUtils + fixes 2015-10-16 09:11:22 +02:00
Stephane Maldini 80f9a21b9d Tweaks to ByteBufPubInputStream to use available blockingQueue facilities 2015-10-16 09:10:07 +02:00
Stephane Maldini b11bef7a26 Eliminate need for rxJava in Json Encoder 2015-10-16 09:07:51 +02:00
Stephane Maldini 985640b6ce Fix ReactorHttpServer with latest changes on shutdown behavior 2015-10-12 11:22:28 +02:00
Sebastien Deleuze 0042a65c53 Await properly Reactor server start/stop
The goal is to try to fix #32
With this change de Reactor test seems to execute slowly.
2015-10-09 11:38:35 +02:00
Sebastien Deleuze 07374f48d6 Move server related classes from src/test to src/main 2015-10-07 14:06:26 +02:00
Stephane Maldini 464ff1d960 Progress #24
Replace Streams fail, empty and Stream map with Publishers.error, empty and map.
Replace Streams calls by Publishers.flatMap, just and Publishers.from
Precise cancel and size to toReadQueue to simulate Promise
Update build
2015-10-07 12:24:32 +01:00
Sebastien Deleuze 0dabdb8207 Add request method based mapping
Closes #22
2015-10-07 12:15:39 +02:00
Sebastien Deleuze 906dead596 Polishing 2015-10-07 12:13:35 +02:00
Stephane Maldini ec1189b0b5 minor fix and update to work on latest 2.1.0.BUILD-SNAPSHOT to use core check in CFUtils 2015-10-05 16:49:25 +01:00
Sebastien Deleuze 32214e0a49 Add Javadoc for main interfaces/classes 2015-10-05 14:18:15 +02:00
Sebastien Deleuze 9516c9992f Return HandlerResult in HandlerAdapter#handle()
This commit updates HandlerAdapter#handle() to return HandlerResult
instead of Publisher<HandlerResult>. A new SimpleHandlerResultHandler
class has been introduced for handlers returning Publisher<Void>.
2015-10-02 20:09:27 +02:00
Sebastien Deleuze 49fc32e214 Check new snapshots for every build 2015-10-01 17:07:13 +02:00
Stephane Maldini 43c23cb775 Merge pull request #21 from spring-projects/update-reactor-next
Update reactor next
2015-09-30 15:25:18 +01:00
Stephane Maldini 0b9bfe6aa2 Merge pull request #20 from spring-projects/add-reactor-net
Add reactor net
2015-09-30 15:24:59 +01:00
Stephane Maldini d20fbffcd0 Update to Reactor 2.1.0.BUILD-SNAPSHOT 2015-09-29 23:31:02 +01:00
Stephane Maldini 4ffec61310 Update to 2.0.6 snapshot for Header sent too soon fix, which allows DispatcherHandler to assign content-type correctly. 2015-09-29 23:16:06 +01:00
Stephane Maldini 20c4011094 initialize reactor support, not passing requestmapping tests yet 2015-09-29 14:07:36 +01:00
Sebastien Deleuze f816cc6a51 Add CompletableFuture/Single/Promise support 2015-09-24 23:02:49 +02:00
Sebastien Deleuze 6716f969d6 Update README.md with artifact infos 2015-09-22 12:27:34 +02:00
Sebastien Deleuze ba66de0dc3 Set Gradle project name for CI 2015-09-22 12:14:02 +02:00
João Pedro Evangelista d3e5d9dd03 Polishing 2015-09-22 09:14:29 +02:00
Sebastien Deleuze 110d9d7cd9 Use ByteBuffer instead of byte[] 2015-09-22 08:02:57 +02:00
Sebastien Deleuze 9cbe984598 Create README.md 2015-09-21 09:48:30 +02:00
Sebastien Deleuze 77c5b3fd65 Fix RxNetty tests by finding a new port for each test 2015-09-17 14:25:57 -04:00
Stephane Maldini 6da7453517 Merge remote-tracking branch 'origin/master' 2015-09-11 17:06:50 -04:00
Sebastien Deleuze 4d29110cd7 Polish Gradle configuration for deployment 2015-09-11 22:46:44 +02:00
Stephane Maldini 5e39858780 ignore for now 2015-09-11 16:09:49 -04:00
Sebastien Deleuze 870c1ae43b Polishing 2015-09-10 18:39:17 +02:00
Sebastien Deleuze ca1ec24aa9 Define the group to use for the dependency 2015-09-10 18:06:38 +02:00
Sebastien Deleuze 3f6301648e Update version to 0.1.0.BUILD-SNAPSHOT 2015-09-10 17:48:29 +02:00
Sebastien Deleuze 3fd0f60618 Polish integration tests 2015-09-10 17:44:06 +02:00
Sebastien Deleuze 881db0688b Add Codec support
This commit adds support for Publisher based codecs that allows to convert
byte stream to object stream and vice & versa.

Jackson, JAXB2 and String codec implementations are provided.
2015-09-10 13:47:54 +02:00
Sebastien Deleuze 5ddbbf4673 Rename XMLHandler.java to XmlHandler.java 2015-09-10 13:31:42 +02:00
Arjen Poutsma 01ef90f1ca Fixed tests. 2015-09-10 11:36:14 +02:00
Arjen Poutsma df31c94d7f Merge branch 'master' of github.com:spring-projects/spring-reactive
# Conflicts:
#	src/test/java/org/springframework/reactive/io/ByteArrayPublisherInputStreamTests.java
2015-09-10 11:23:05 +02:00
Arjen Poutsma 0b19fca73a Added cancellation logic to RequestBodyPublisher. 2015-09-10 11:18:51 +02:00
Arjen Poutsma 5bbeb9c204 Removed BlockingSignalQueue in favor of PublisherSignal. 2015-09-10 11:05:30 +02:00
Sebastien Deleuze e47069775c Update dependencies (Spring 4.2.1, Tomcat 8.0.26, Jetty 9.3.3)
This commit also polishes build.gradle to use double quotes consistently.
2015-09-08 14:23:35 +02:00
Sebastien Deleuze 357ce225f3 Polishing 2015-09-07 16:00:19 +02:00
Sebastien Deleuze edb0fcefaf Update RxNetty artifactId to use their latest Snapshot 2015-09-07 15:53:36 +02:00
Arjen Poutsma 0ec29d1c67 Fixed stalling issue in RequestBodyPublisher. 2015-09-04 13:33:02 +02:00
Sebastien Deleuze c1f179677a Polishing 2015-08-27 20:18:18 +02:00
Rossen Stoyanchev 202825554c Add basic support for @RequestMapping
Just enough for a test with an @ResponseBody method that accepts an
@RequestParam String arg and returning Publisher<String> or String.

See RequestMappingIntegrationTests.
2015-08-25 12:45:46 -04:00
Sebastien Deleuze 9df3dd4495 Polish build.gradle 2015-08-25 14:39:36 +02:00
Rossen Stoyanchev bc7a5acd50 Add simple URL mapping and handling
This commit adds support for simple URL handler mapping (exact path
match) and an adapter for the HttpHandler interface to be used to
handle the request.

The SimpleUrlHandlerMappingIntegrationTests then maps the URLs
"/foo" and "/bar" to two different handlers.
2015-08-24 17:33:01 -04:00
Rossen Stoyanchev d6fd274771 Add HttpServer and Jetty/Tomcat/RxNetty implementations
This is a refactoring of the existing "echo" integration test with the
goal to make it easier to add further integration tests.

The HttpServer abstraction is on the test source side for now.
2015-08-24 16:33:22 -04:00
Rossen Stoyanchev f020a1add1 Refactor package structure
Introduce http and dispatch packages under org.springframework.web to
separate HTTP-specific adapter code from higher level web framework
code. Move classes into their respective locations.
2015-08-24 14:41:58 -04:00
Rossen Stoyanchev 56d6940485 Replace Promises.error->Streams.fail, concatMap->map 2015-08-24 14:03:36 -04:00
Rossen Stoyanchev 6634d1f536 Use Streams from reactor-streams 2015-08-17 18:36:18 -04:00
Rossen Stoyanchev 69d4eaaa3c Use PublisherFactory from reactor-core 2015-08-17 16:52:39 -04:00
Rossen Stoyanchev 773d0444bf Add request handling infrastructure
HandlerMapping, HandlerAdapter, HandlerResultHandler (+ HandlerResult)
as the basic request handling contracts. DispatcherHandler to drive
overall request handling.

DispatcherApp provides minimal implementations of the above contracts
enough to put together a running example that returns
200 text/plain "Hello world".
2015-08-17 15:54:06 -04:00
Rossen Stoyanchev c682895dee Add RxNetty support
This commit adds RxNetty integration that includes RxNetty-based
implementations of ServerHttpRequest and ServerHttpResponse as well as
an adapter from the RxNetty RequestHandler to the HttpHandler contracts.

Only byte[] is supported at the moment for reading and writing with a
corresponding copy to and from Netty ByteBuf.
2015-08-11 16:17:34 -04:00
Rossen Stoyanchev 2cb32a0fd6 Add ServerHttpRequest & ServerHttpResponse
This commit introduces HTTP request and response abstractions along
with Servlet-based implementations similar to the ones in the http
package of spring-web but using Reactive Streams.

In turn HttpHandler now accepts the request and response types and
returns Publisher<Void> that reflects the end of handling.

The write method on the response also returns Publisher<Void> allowing
deferred writing. At the moment however the underlying Servlet 3.1
support only supports a single publisher after which the connection
is closed.

Only simple byte[] is supported for reading and writing.
2015-08-11 16:09:51 -04:00
Rossen Stoyanchev bb25267525 Fix whitespaces in build.gradle 2015-08-10 14:18:59 -04:00
Rossen Stoyanchev e770b7de41 Tests pass
For Tomcat, failures occur if HttpHandlerServlet buffer size is
significantly less than the Tomcat input buffer size.

Also on command line Jetty tests fail with port unavailable unless
the server from the Tomcat tests is also destroyed.
2015-08-08 03:57:29 -04:00
Rossen Stoyanchev 17b3db2988 Add gradle wrapper 2015-08-08 03:57:29 -04:00
Rossen Stoyanchev c464cddf83 Update versions 2015-08-08 03:57:23 -04:00
Arjen Poutsma 3595c51d40 Introduced DemandCounter 2015-07-29 14:21:10 +02:00
Arjen Poutsma 74a29ac146 Renamed 'rx' package to 'reactive' 2015-07-09 13:42:48 +02:00
Arjen Poutsma f518d76a77 Working version of Servlet 3.1 <-> RS bridge. 2015-07-07 12:53:45 +02:00
Arjen Poutsma 3b45087c87 work, work. 2015-07-01 15:03:14 +02:00
Arjen Poutsma c552aaa6f1 work, work. 2015-06-30 13:45:54 +02:00
Arjen Poutsma 342299abf6 Initial commit 2015-06-05 15:38:50 +02:00
7571 changed files with 116805 additions and 207299 deletions
+1
View File
@@ -17,6 +17,7 @@ argfile*
pom.xml
activemq-data/
classes/
/build
buildSrc/build
/spring-*/build
+2 -2
View File
@@ -40,5 +40,5 @@ appropriate to the circumstances. Maintainers are obligated to maintain confiden
with regard to the reporter of an incident.
This Code of Conduct is adapted from the
https://contributor-covenant.org[Contributor Covenant], version 1.3.0, available at
https://contributor-covenant.org/version/1/3/0/[contributor-covenant.org/version/1/3/0/]
http://contributor-covenant.org[Contributor Covenant], version 1.3.0, available at
http://contributor-covenant.org/version/1/3/0/[contributor-covenant.org/version/1/3/0/]
+5 -5
View File
@@ -1,6 +1,6 @@
= How to contribute to the reference
The Spring Framework reference now uses https://asciidoctor.org/[asciidoctor]. This
The Spring Framework reference now uses http://asciidoctor.org/[asciidoctor]. This
document describes how to contribute documentation updates.
== Building with Gradle
@@ -18,7 +18,7 @@ One of the nice features about using asciidoctor is the support for live editing
You will find a Guardfile already present at `spring-framework/src/asciidoc/Guardfile`.
Make sure first to follow the setup instructions within the
https://asciidoctor.org/docs/editing-asciidoc-with-live-preview/[Editing AsciiDoc with Live Preview]
http://asciidoctor.org/docs/editing-asciidoc-with-live-preview/[Editing AsciiDoc with Live Preview]
document. Once you have done that, there are additional gems to install to make it work
(assuming that you are using http://livereload.com/[LiveReload]):
@@ -45,7 +45,7 @@ Some notes on documentation
* Documentation is wrapped at 90 chars, ensure that you manually wrap your edits
* Tabs are used for indentation, do not use spaces
* Follow the existing style when inserting `source` blocks
* https://asciidoctor.org/docs/asciidoc-syntax-quick-reference/[Asciidoctor Quick Reference]
* https://asciidoctor.org/docs/user-manual/[Asciidoctor Manual]
* https://asciidoctor.org/docs/asciidoc-writers-guide/[Asciidoctor Writers Guide]
* http://asciidoctor.org/docs/asciidoc-syntax-quick-reference/[Asciidoctor Quick Reference]
* http://asciidoctor.org/docs/user-manual/[Asciidoctor Manual]
* http://asciidoctor.org/docs/asciidoc-writers-guide/[Asciidoctor Writers Guide]
+10 -25
View File
@@ -33,32 +33,18 @@ do not find something similar, please create a new JIRA issue before submitting
a pull request unless the change is truly trivial -- for example: typo fixes,
removing compiler warnings, etc.
### Sign the Individual Contributor License Agreement (ICLA)
### Sign the Contributor License Agreement (CLA)
If you have not previously done so, please fill out and submit the
[Spring ICLA form][]. You'll receive a token when this process is complete.
Keep track of this; you may be asked for it later!
Note that emailing/postal mailing a signed copy is _not_ necessary. Submission
of the web form is all that is required.
Once you've completed the web form, simply add the following in a comment on
your pull request:
I have signed and agree to the terms of the Spring Individual Contributor
License Agreement.
You do not need to include your token/id. Please add the above statement to all
future pull requests as well, simply so that the Spring Framework team knows
immediately that this process is complete.
If you have not previously done so, please sign the [Contributor License Agreement][].
If you forget to do so, you'll be reminded when you submit a pull request.
## Create a Branch
### Branch from `master`
Master currently represents work toward Spring Framework 4.0. Please submit
Master currently represents work toward Spring Framework 5.0. Please submit
all pull requests there, even bug fixes and minor improvements. Backports to
`3.2.x` will be considered on a case-by-case basis.
`4.3.x` will be considered on a case-by-case basis.
### Use short branch names
@@ -101,7 +87,7 @@ present in the framework.
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
@@ -308,12 +294,11 @@ Note that you can always force push (`git push -f`) reworked / rebased commits
against the branch used to submit your pull request. In other words, you do not
need to issue a new pull request when asked to make changes.
[help documentation]: https://help.github.com/send-pull-requests
[help documentation]: https://help.github.com/categories/collaborating-on-projects-using-issues-and-pull-requests/
[JIRA issue tracker]: https://jira.spring.io/browse/SPR
[spring-framework-contrib]: https://groups.google.com/forum/#!forum/spring-framework-contrib
[Spring ICLA form]: https://support.springsource.com/spring_committer_signup
[Contributor License Agreement]: https://cla.pivotal.io/sign/spring
[fork-and-edit]: https://github.com/blog/844-forking-with-the-edit-button
[Spring Framework Code Style]: https://github.com/spring-projects/spring-framework/wiki/Spring-Framework-Code-Style
[Rewriting History section of Pro Git]: https://git-scm.com/book/en/Git-Tools-Rewriting-History
[Commit Guidelines section of Pro Git]: https://git-scm.com/book/en/Distributed-Git-Contributing-to-a-Project#Commit-Guidelines
[Rewriting History section of Pro Git]: http://git-scm.com/book/en/Git-Tools-Rewriting-History
[Commit Guidelines section of Pro Git]: http://git-scm.com/book/en/Distributed-Git-Contributing-to-a-Project#Commit-Guidelines
[building from source]: https://github.com/spring-projects/spring-framework#building-from-source
+14 -14
View File
@@ -74,29 +74,29 @@ The Spring Framework is released under version 2.0 of the [Apache License][].
[Spring Integration]: https://github.com/spring-projects/spring-integration
[Spring Batch]: https://github.com/spring-projects/spring-batch
[family of projects]: https://spring.io/projects
[family of projects]: http://spring.io/projects
[Spring organization]: https://github.com/spring-projects
[downloading Spring artifacts]: https://github.com/spring-projects/spring-framework/wiki/Downloading-Spring-artifacts
[building a distribution with dependencies]: https://github.com/spring-projects/spring-framework/wiki/Building-a-distribution-with-dependencies
[Javadoc]: https://docs.spring.io/spring-framework/docs/current/javadoc-api/
[reference docs]: https://docs.spring.io/spring-framework/docs/current/spring-framework-reference/
[spring tags]: https://spring.io/questions
[Stack Overflow]: https://stackoverflow.com/faq
[Commercial support]: https://spring.io/services
[Javadoc]: http://docs.spring.io/spring-framework/docs/current/javadoc-api/
[reference docs]: http://docs.spring.io/spring-framework/docs/current/spring-framework-reference/
[spring tags]: http://spring.io/questions
[Stack Overflow]: http://stackoverflow.com/faq
[Commercial support]: http://spring.io/services
[Spring Framework JIRA]: https://jira.spring.io/browse/SPR
[the lifecycle of an issue]: https://github.com/spring-projects/spring-framework/wiki/The-Lifecycle-of-an-Issue
[spring-framework-issues]: https://github.com/spring-projects/spring-framework-issues#readme
[readme]: https://github.com/spring-projects/spring-framework-issues#readme
[Gradle]: https://gradle.org
[`./gradlew`]: https://vimeo.com/34436402
[Git]: https://help.github.com/set-up-git-redirect
[JDK8 build]: https://www.oracle.com/technetwork/java/javase/downloads
[Gradle]: http://gradle.org
[`./gradlew`]: http://vimeo.com/34436402
[Git]: http://help.github.com/set-up-git-redirect
[JDK8 build]: http://www.oracle.com/technetwork/java/javase/downloads
[Gradle build and release FAQ]: https://github.com/spring-projects/spring-framework/wiki/Gradle-build-and-release-FAQ
[Pull requests]: https://help.github.com/send-pull-requests
[Pull requests]: https://help.github.com/categories/collaborating-on-projects-using-issues-and-pull-requests/
[contributor guidelines]: https://github.com/spring-projects/spring-framework/blob/master/CONTRIBUTING.md
[@SpringFramework]: https://twitter.com/springframework
[@SpringCentral]: https://twitter.com/springcentral
[team members]: https://twitter.com/springframework/lists/team/members
[The Spring Blog]: https://spring.io/blog/
[news feed]: https://spring.io/blog/category/news
[Apache License]: https://www.apache.org/licenses/LICENSE-2.0
[The Spring Blog]: http://spring.io/blog/
[news feed]: http://spring.io/blog/category/news
[Apache License]: http://www.apache.org/licenses/LICENSE-2.0
+436 -366
View File
File diff suppressed because it is too large Load Diff
@@ -64,6 +64,7 @@ class MergePlugin implements Plugin<Project> {
project.plugins.apply(IdeaPlugin)
MergeModel model = project.extensions.create("merge", MergeModel)
model.project = project
project.configurations.create("merging")
Configuration runtimeMerge = project.configurations.create("runtimeMerge")
@@ -76,6 +77,7 @@ class MergePlugin implements Plugin<Project> {
if (it.merge.into != null) {
setup(it)
}
setupIdeDependencies(it)
}
// Hook to build runtimeMerge dependencies
@@ -114,6 +116,16 @@ class MergePlugin implements Plugin<Project> {
}
}
private void setupIdeDependencies(Project project) {
project.configurations.each { c ->
c.dependencies.findAll( { it instanceof org.gradle.api.artifacts.ProjectDependency } ).each { d ->
d.dependencyProject.merge.from.each { from ->
project.dependencies.add("runtimeMerge", from)
}
}
}
}
private void setupMaven(Project project) {
project.configurations.each { configuration ->
Conf2ScopeMapping mapping = project.conf2ScopeMappings.getMapping([configuration])
@@ -154,5 +166,12 @@ class MergePlugin implements Plugin<Project> {
}
class MergeModel {
Project project;
Project into;
List<Project> from = [];
public void setInto(Project into) {
this.into = into;
into.merge.from.add(project);
}
}
+1 -1
View File
@@ -1 +1 @@
version=4.3.31.BUILD-SNAPSHOT
version=5.0.0.M2
+2 -2
View File
@@ -11,7 +11,7 @@ eclipse.jdt {
}
// Replace classpath entries with project dependencies (GRADLE-1116)
// https://issues.gradle.org/browse/GRADLE-1116
// http://issues.gradle.org/browse/GRADLE-1116
eclipse.classpath.file.whenMerged { classpath ->
def regexp = /.*?\/([^\/]+)\/build\/[^\/]+\/(?:main|test)/ // only match those that end in main or test (avoids removing necessary entries like build/classes/jaxb)
def projectOutputDependencies = classpath.entries.findAll { entry -> entry.path =~ regexp }
@@ -21,7 +21,7 @@ eclipse.classpath.file.whenMerged { classpath ->
def projectName = matcher[0][1]
def path = "/${projectName}"
if(!classpath.entries.find { e -> e instanceof ProjectDependency && e.path == path }) {
def dependency = new ProjectDependency(path)
def dependency = new ProjectDependency(path, project(":${projectName}").path)
dependency.exported = true
classpath.entries.add(dependency)
}
+3 -3
View File
@@ -11,7 +11,7 @@ difference between two public Java APIs.
The file jdiff.html contains the reference page for JDiff. The latest
version of JDiff can be downloaded at:
https://sourceforge.net/projects/javadiff
http://sourceforge.net/projects/javadiff
To use the Ant task on your own project, see example.xml. More examples
of using JDiff to compare the public APIs of J2SE1.3 and J2SE1.4 can
@@ -40,7 +40,7 @@ Acknowledgements
JDiff uses Stuart D. Gathman's Java translation of Gene Myers' O(ND)
difference algorithm.
JDiff uses Xerces 1.4.2 from https://www.apache.org.
JDiff uses Xerces 1.4.2 from http://www.apache.org.
JDiff also includes a script to use the classdoc application from
http://classdoc.sourceforge.net or http://www.jensgulden.de, by Jens
@@ -56,4 +56,4 @@ much of this work.
Footnote:
If you are looking for a generalized diff tool for XML, try diffmk from
https://wwws.sun.com/software/xml/developers/diffmk/
http://wwws.sun.com/software/xml/developers/diffmk/
+11 -11
View File
@@ -7,10 +7,10 @@
<BODY BGCOLOR="#ffffff">
<table width="100%">
<tr>
<td align="left"><A href="https://sourceforge.net/projects/javadiff/">
<td align="left"><A href="http://sourceforge.net/projects/javadiff/">
<IMG src="http://javadiff.cvs.sourceforge.net/*checkout*/javadiff/jdiff/lib/jdiff_logo.gif"
width="88" height="31" border="0" alt="JDiff Logo"></A></td>
<td align="right"><A href="https://sourceforge.net"> <IMG src="https://sourceforge.net/sflogo.php?group_id=37160" width="88" height="31" border="0" alt="SourceForge Logo"></A></td>
<td align="right"><A href="http://sourceforge.net"> <IMG src="http://sourceforge.net/sflogo.php?group_id=37160" width="88" height="31" border="0" alt="SourceForge Logo"></A></td>
</tr>
</table>
@@ -21,7 +21,7 @@ width="88" height="31" border="0" alt="JDiff Logo"></A></td>
<BLOCKQUOTE>
<b>JDiff</b> is a Javadoc <a
href="https://java.sun.com/j2se/javadoc">doclet</a> which generates an
href="http://java.sun.com/j2se/javadoc">doclet</a> which generates an
HTML report of all the packages, classes, constructors, methods, and
fields which have been removed, added or changed in any way, including
their documentation, when two APIs are compared. This is very useful
@@ -312,7 +312,7 @@ the HTML output to the given directory.
<code>-javadocnew</code> &lt;<i>javadoc files location for the new API</i>></DT>
<DD STYLE="margin-right: 2cm; margin-bottom: 0.5cm">
The location of existing Javadoc files
for the new API, e.g. "https://java.sun.com/j2se/<b>1.5.0</b>/docs/api/" for the
for the new API, e.g. "http://java.sun.com/j2se/<b>1.5.0</b>/docs/api/" for the
public documentation for J2SE1.5.0. The default value is "../", which implies
that the documentation directory generated by Javadoc is at the same level as
the "changes.html" file generated by JDiff. Slashes are always
@@ -325,7 +325,7 @@ the HTML output to the given directory.
<DT STYLE="margin-right: 2cm; margin-bottom: 0.5cm">
<code>-javadocold</code> &lt;<i>javadoc files location for the old API</i>></DT>
<DD STYLE="margin-right: 2cm; margin-bottom: 0.5cm"> The location of existing
Javadoc files for the old API, e.g. "https://java.sun.com/j2se/<b>1.5.0</b>/docs/API/"
Javadoc files for the old API, e.g. "http://java.sun.com/j2se/<b>1.5.0</b>/docs/API/"
for the public documentation for J2SE1.5.0. The default value is null, which
results in no links to Javadoc-generated documentation for the previous
release. Slashes are always forward in the argument, since this is an HTML
@@ -426,7 +426,7 @@ the HTML output to the given directory.
<code>-showallchanges</code></DT>
<DD STYLE="margin-right: 2cm; margin-bottom: 0.5cm">
If this argument is used, JDiff will show changes in
native and synchronized modifiers. See <a href="https://java.sun.com/j2se/1.4.1/docs/tooldocs/solaris/javadoc.html#generatedapideclarations">here</a> for why these are not shown by default.
native and synchronized modifiers. See <a href="http://java.sun.com/j2se/1.4.1/docs/tooldocs/solaris/javadoc.html#generatedapideclarations">here</a> for why these are not shown by default.
</DD>
<DT STYLE="margin-right: 2cm; margin-bottom: 0.5cm">
@@ -547,7 +547,7 @@ moved to the end of the file and placed inside XML comments.
<BLOCKQUOTE> The text which is added can be HTML text if necessary, but if the
HTML is incorrect, JDiff may fail to read the comments file and exit. Note that
the required HTML is in fact <a href="https://www.w3.org/TR/xhtml1/diffs.html">XHTML</a>. Since this HTML is stored in an XML document, single tags without their closing ("slash") element are not permitted.
the required HTML is in fact <a href="http://www.w3.org/TR/xhtml1/diffs.html">XHTML</a>. Since this HTML is stored in an XML document, single tags without their closing ("slash") element are not permitted.
For example, most browsers permit HTML which looks like "&lt;p>Here is some
text.", with no closing tag. XML requires that either a closing tag exists ("&lt;/p>"),
or that the single tag is closed, e.g. "&lt;p/>Here is some text.".
@@ -988,7 +988,7 @@ it can tell you how the content has changed.
Nor does it
compare what the methods in an API do; if JDiff could tell you what had changed about the way two
versions of an API execute, the <a
href="https://en.wikipedia.org/wiki/Halting_Problem">Halting
href="http://en.wikipedia.org/wiki/Halting_Problem">Halting
Problem</a> would be solved, and our lives would be very different.</li>
<li>On a P3 450MHz machine, to scan all of the J2SE <code>Java</code>
and <code>javax</code> packages and generate XML takes about 2 minutes
@@ -1002,14 +1002,14 @@ per version. To generate a report from the XML files takes about 30s</li>
<BLOCKQUOTE>
<UL>
<LI><A HREF="https://www.sys-con.com/java">Java Developer's Journal
<LI><A HREF="http://www.sys-con.com/java">Java Developer's Journal
</A>, April 2002 contained an article about JDiff. The article
can also be <a
href="http://javadiff.cvs.sourceforge.net/*checkout*/javadiff/jdiff/doc/JDiffArticle.pdf">found
here</a>.</LI>
<LI><A HREF="https://java.sun.com/j2se/javadoc/">Javadoc</A> and Doclet
<LI><A HREF="http://java.sun.com/j2se/javadoc/">Javadoc</A> and Doclet
documentation from Sun.</LI>
<LI><A HREF="https://java.sun.com/j2se/javadoc/faq.html#doclets">Third-party
<LI><A HREF="http://java.sun.com/j2se/javadoc/faq.html#doclets">Third-party
doclets</a> as listed by Sun.</LI>
<LI><A HREF="http://www.doclet.com">Third-party doclets</a> as listed by others.</LI>
</UL>
+3 -3
View File
@@ -25,12 +25,12 @@ def customizePom(pom, gradleProject) {
url = "https://github.com/spring-projects/spring-framework"
organization {
name = "Spring IO"
url = "https://projects.spring.io/spring-framework"
url = "http://projects.spring.io/spring-framework"
}
licenses {
license {
name "Apache License, Version 2.0"
url "https://www.apache.org/licenses/LICENSE-2.0"
name "The Apache Software License, Version 2.0"
url "http://www.apache.org/licenses/LICENSE-2.0.txt"
distribution "repo"
}
}
Binary file not shown.
+2 -1
View File
@@ -1,5 +1,6 @@
#Mon Aug 15 21:03:22 CEST 2016
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-4.10.2-bin.zip
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-3.0-bin.zip
Vendored
+10 -13
View File
@@ -1,4 +1,4 @@
#!/usr/bin/env sh
#!/usr/bin/env bash
##############################################################################
##
@@ -34,11 +34,11 @@ DEFAULT_JVM_OPTS=""
# Use the maximum available, or set MAX_FD != -1 to use that value.
MAX_FD="maximum"
warn () {
warn ( ) {
echo "$*"
}
die () {
die ( ) {
echo
echo "$*"
echo
@@ -155,19 +155,16 @@ if $cygwin ; then
esac
fi
# Escape application args
save () {
for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done
echo " "
# Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules
function splitJvmOpts() {
JVM_OPTS=("$@")
}
APP_ARGS=$(save "$@")
# Collect all arguments for the java command, following the shell quoting and substitution rules
eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS"
eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS
JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME"
# by default we should be in the correct project dir, but when run from Finder on Mac, the cwd is wrong
if [ "$(uname)" = "Darwin" ] && [ "$HOME" = "$PWD" ]; then
if [[ "$(uname)" == "Darwin" ]] && [[ "$HOME" == "$PWD" ]]; then
cd "$(dirname "$0")"
fi
exec "$JAVACMD" "$@"
exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@"
+1 -1
View File
@@ -17,7 +17,7 @@ echo been tested against STS %STS_TEST_VERSION%), but at the minimum you will
echo need Eclipse + AJDT.
echo.
echo If you need to download and install STS, please do that now by
echo visiting https://spring.io/tools/sts/all
echo visiting http://spring.io/tools/sts/all
echo.
echo Otherwise, press enter and we'll begin.
+3 -3
View File
@@ -19,9 +19,9 @@ This script has been tested against:
If you need to download and install Eclipse or STS, please do that now
by visiting one of the following sites:
- Eclipse downloads: https://download.eclipse.org/eclipse/downloads
- STS downloads: https://spring.io/tools/sts/all
- STS nightly builds: https://dist.springsource.com/snapshot/STS/nightly-distributions.html
- Eclipse downloads: http://download.eclipse.org/eclipse/downloads
- STS downloads: http://spring.io/tools/sts/all
- STS nightly builds: http://dist.springsource.com/snapshot/STS/nightly-distributions.html
If you need to install a recent CI build for AJDT (i.e., so that the
spring-aspects module properly compiles in Eclipse/STS), click on the
+16 -15
View File
@@ -1,26 +1,27 @@
The following has been tested against Intellij IDEA 13.1
The following has been tested against IntelliJ IDEA 2016.2.2
## Steps
_Within your locally cloned spring-framework working directory:_
1. Pre-compile `spring-oxm` with `./gradlew cleanIdea :spring-oxm:compileTestJava`
2. Import into IDEA (File->import project->import from external model->Gradle)
3. Set the Project JDK as appropriate (1.8+)
4. Exclude the `spring-aspects` module (Go to File->Project Structure->Modules)
5. Code away
1. Precompile `spring-oxm` with `./gradlew cleanIdea :spring-oxm:compileTestJava`
2. Import into IntelliJ (File -> New -> Project from Existing Sources -> Navigate to directory -> Select build.gradle)
3. When prompted exclude the `spring-aspects` module (or after the import via File-> Project Structure -> Modules)
4. Code away
## Known issues
1. `spring-oxm` should be pre-compiled since it's using repackaged dependencies (see *RepackJar tasks)
2. `spring-aspects` does not compile out of the box due to references to aspect types unknown to IDEA.
See https://youtrack.jetbrains.com/issue/IDEA-64446 for details. In the meantime, the 'spring-aspects'
should be excluded from the overall project to avoid compilation errors.
3. While all JUnit tests pass from the command line with Gradle, many will fail when run from IDEA.
Resolving this is a work in progress. If attempting to run all JUnit tests from within IDEA, you will
likely need to set the following VM options to avoid out of memory errors:
1. `spring-core` and `spring-oxm` should be pre-compiled due to repackaged dependencies.
See `*RepackJar` tasks in the build and https://youtrack.jetbrains.com/issue/IDEA-160605).
2. `spring-aspects` does not compile due to references to aspect types unknown to
IntelliJ IDEA. See http://youtrack.jetbrains.com/issue/IDEA-64446 for details. In the meantime, the
'spring-aspects' can be excluded from the project to avoid compilation errors.
3. While JUnit tests pass from the command line with Gradle, some may fail when run from
IntelliJ IDEA. Resolving this is a work in progress. If attempting to run all JUnit tests from within
IntelliJ IDEA, you will likely need to set the following VM options to avoid out of memory errors:
-XX:MaxPermSize=2048m -Xmx2048m -XX:MaxHeapSize=2048m
## Tips
In any case, please do not check in your own generated .iml, .ipr, or .iws files.
@@ -28,6 +29,6 @@ You'll notice these files are already intentionally in .gitignore. The same poli
## FAQ
Q. What about IDEA's own [Gradle support](https://confluence.jetbrains.net/display/IDEADEV/Gradle+integration)?
Q. What about IntelliJ IDEA's own [Gradle support](http://confluence.jetbrains.net/display/IDEADEV/Gradle+integration)?
A. Keep an eye on https://youtrack.jetbrains.com/issue/IDEA-53476
A. Keep an eye on http://youtrack.jetbrains.com/issue/IDEA-53476
+2 -5
View File
@@ -6,23 +6,20 @@ include "spring-beans"
include "spring-beans-groovy"
include "spring-context"
include "spring-context-support"
include "spring-context-indexer"
include "spring-core"
include "spring-expression"
include "spring-instrument"
include "spring-instrument-tomcat"
include "spring-jdbc"
include "spring-jms"
include "spring-messaging"
include "spring-orm"
include "spring-orm-hibernate4"
include "spring-orm-hibernate5"
include "spring-oxm"
include "spring-test"
include "spring-tx"
include "spring-web"
include "spring-webmvc"
include "spring-webmvc-portlet"
include "spring-webmvc-tiles2"
include "spring-web-reactive"
include "spring-websocket"
include "spring-framework-bom"
@@ -5,7 +5,7 @@
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
@@ -5,7 +5,7 @@
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
@@ -5,7 +5,7 @@
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
@@ -5,7 +5,7 @@
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
@@ -5,7 +5,7 @@
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
@@ -5,7 +5,7 @@
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
@@ -5,7 +5,7 @@
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
@@ -5,7 +5,7 @@
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
@@ -39,6 +39,7 @@ package org.aopalliance.intercept;
*
* @author Rod Johnson
*/
@FunctionalInterface
public interface MethodInterceptor extends Interceptor {
/**
@@ -5,7 +5,7 @@
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
@@ -5,7 +5,7 @@
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
@@ -5,7 +5,7 @@
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
@@ -5,7 +5,7 @@
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
@@ -5,7 +5,7 @@
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
@@ -5,7 +5,7 @@
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
@@ -1,11 +1,11 @@
/*
* Copyright 2002-2007 the original author or authors.
* Copyright 2002-2016 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.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
@@ -27,6 +27,7 @@ package org.springframework.aop;
* @see Pointcut
* @see MethodMatcher
*/
@FunctionalInterface
public interface ClassFilter {
/**
@@ -5,7 +5,7 @@
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
@@ -5,7 +5,7 @@
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
@@ -5,7 +5,7 @@
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
@@ -5,7 +5,7 @@
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
@@ -5,7 +5,7 @@
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
@@ -5,7 +5,7 @@
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
@@ -1,11 +1,11 @@
/*
* Copyright 2002-2018 the original author or authors.
* Copyright 2002-2015 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.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
@@ -48,11 +48,10 @@ import java.lang.reflect.Method;
public interface MethodMatcher {
/**
* Perform static checking whether the given method matches.
* <p>If this returns {@code false} or if the {@link #isRuntime()}
* method returns {@code false}, no runtime check (i.e. no
* {@link #matches(java.lang.reflect.Method, Class, Object[])} call)
* will be made.
* Perform static checking whether the given method matches. If this
* returns {@code false} or if the {@link #isRuntime()} method
* returns {@code false}, no runtime check (i.e. no.
* {@link #matches(java.lang.reflect.Method, Class, Object[])} call) will be made.
* @param method the candidate method
* @param targetClass the target class (may be {@code null}, in which case
* the candidate class must be taken to be the method's declaring class)
@@ -5,7 +5,7 @@
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
@@ -5,7 +5,7 @@
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
@@ -5,7 +5,7 @@
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
@@ -5,7 +5,7 @@
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
@@ -5,7 +5,7 @@
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
@@ -5,7 +5,7 @@
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
@@ -1,11 +1,11 @@
/*<
* Copyright 2002-2017 the original author or authors.
* Copyright 2002-2012 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.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
@@ -34,8 +34,9 @@ public interface TargetSource extends TargetClassAware {
/**
* Return the type of targets returned by this {@link TargetSource}.
* <p>Can return {@code null}, although certain usages of a {@code TargetSource}
* might just work with a predetermined target class.
* <p>Can return {@code null}, although certain usages of a
* {@code TargetSource} might just work with a predetermined
* target class.
* @return the type of targets returned by this {@link TargetSource}
*/
@Override
@@ -43,8 +44,9 @@ public interface TargetSource extends TargetClassAware {
/**
* Will all calls to {@link #getTarget()} return the same object?
* <p>In that case, there will be no need to invoke {@link #releaseTarget(Object)},
* and the AOP framework can cache the return value of {@link #getTarget()}.
* <p>In that case, there will be no need to invoke
* {@link #releaseTarget(Object)}, and the AOP framework can cache
* the return value of {@link #getTarget()}.
* @return {@code true} if the target is immutable
* @see #getTarget
*/
@@ -53,15 +55,14 @@ public interface TargetSource extends TargetClassAware {
/**
* Return a target instance. Invoked immediately before the
* AOP framework calls the "target" of an AOP method invocation.
* @return the target object which contains the joinpoint,
* or {@code null} if there is no actual target instance
* @return the target object, which contains the joinpoint
* @throws Exception if the target object can't be resolved
*/
Object getTarget() throws Exception;
/**
* Release the given target object obtained from the
* {@link #getTarget()} method, if any.
* {@link #getTarget()} method.
* @param target object obtained from a call to {@link #getTarget()}
* @throws Exception if the object can't be released
*/
@@ -5,7 +5,7 @@
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
@@ -5,7 +5,7 @@
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
@@ -5,7 +5,7 @@
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
@@ -5,7 +5,7 @@
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
@@ -1,11 +1,11 @@
/*
* Copyright 2002-2018 the original author or authors.
* Copyright 2002-2016 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.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
@@ -103,8 +103,8 @@ public abstract class AbstractAspectJAdvice implements Advice, AspectJPrecedence
private final AspectInstanceFactory aspectInstanceFactory;
/**
* The name of the aspect (ref bean) in which this advice was defined
* (used when determining advice precedence so that we can determine
* The name of the aspect (ref bean) in which this advice was defined (used
* when determining advice precedence so that we can determine
* whether two pieces of advice come from the same aspect).
*/
private String aspectName;
@@ -118,13 +118,13 @@ public abstract class AbstractAspectJAdvice implements Advice, AspectJPrecedence
* This will be non-null if the creator of this advice object knows the argument names
* and sets them explicitly
*/
private String[] argumentNames;
private String[] argumentNames = null;
/** Non-null if after throwing advice binds the thrown value */
private String throwingName;
private String throwingName = null;
/** Non-null if after returning advice binds the return value */
private String returningName;
private String returningName = null;
private Class<?> discoveredReturningType = Object.class;
@@ -227,7 +227,7 @@ public abstract class AbstractAspectJAdvice implements Advice, AspectJPrecedence
}
/**
* Set the declaration order of this advice within the aspect.
* Sets the <b>declaration order</b> of this advice within the aspect
*/
public void setDeclarationOrder(int order) {
this.declarationOrder = order;
@@ -260,7 +260,7 @@ public abstract class AbstractAspectJAdvice implements Advice, AspectJPrecedence
}
}
if (this.argumentNames != null) {
if (this.aspectJAdviceMethod.getParameterTypes().length == this.argumentNames.length + 1) {
if (this.aspectJAdviceMethod.getParameterCount() == this.argumentNames.length + 1) {
// May need to add implicit join point arg name...
Class<?> firstArgType = this.aspectJAdviceMethod.getParameterTypes()[0];
if (firstArgType == JoinPoint.class ||
@@ -295,8 +295,8 @@ public abstract class AbstractAspectJAdvice implements Advice, AspectJPrecedence
}
catch (Throwable ex) {
throw new IllegalArgumentException("Returning name '" + name +
"' is neither a valid argument name nor the fully-qualified " +
"name of a Java type on the classpath. Root cause: " + ex);
"' is neither a valid argument name nor the fully-qualified name of a Java type on the classpath. " +
"Root cause: " + ex);
}
}
}
@@ -329,8 +329,8 @@ public abstract class AbstractAspectJAdvice implements Advice, AspectJPrecedence
}
catch (Throwable ex) {
throw new IllegalArgumentException("Throwing name '" + name +
"' is neither a valid argument name nor the fully-qualified " +
"name of a Java type on the classpath. Root cause: " + ex);
"' is neither a valid argument name nor the fully-qualified name of a Java type on the classpath. " +
"Root cause: " + ex);
}
}
}
@@ -366,7 +366,7 @@ public abstract class AbstractAspectJAdvice implements Advice, AspectJPrecedence
* to which argument name. There are multiple strategies for determining
* this binding, which are arranged in a ChainOfResponsibility.
*/
public final synchronized void calculateArgumentBindings() {
public synchronized final void calculateArgumentBindings() {
// The simple case... nothing to bind.
if (this.argumentsIntrospected || this.parameterTypes.length == 0) {
return;
@@ -374,8 +374,10 @@ public abstract class AbstractAspectJAdvice implements Advice, AspectJPrecedence
int numUnboundArgs = this.parameterTypes.length;
Class<?>[] parameterTypes = this.aspectJAdviceMethod.getParameterTypes();
if (maybeBindJoinPoint(parameterTypes[0]) || maybeBindProceedingJoinPoint(parameterTypes[0]) ||
maybeBindJoinPointStaticPart(parameterTypes[0])) {
if (maybeBindJoinPoint(parameterTypes[0]) || maybeBindProceedingJoinPoint(parameterTypes[0])) {
numUnboundArgs--;
}
else if (maybeBindJoinPointStaticPart(parameterTypes[0])) {
numUnboundArgs--;
}
@@ -459,9 +461,9 @@ public abstract class AbstractAspectJAdvice implements Advice, AspectJPrecedence
}
private void bindExplicitArguments(int numArgumentsLeftToBind) {
this.argumentBindings = new HashMap<String, Integer>();
this.argumentBindings = new HashMap<>();
int numExpectedArgumentNames = this.aspectJAdviceMethod.getParameterTypes().length;
int numExpectedArgumentNames = this.aspectJAdviceMethod.getParameterCount();
if (this.argumentNames.length != numExpectedArgumentNames) {
throw new IllegalStateException("Expecting to find " + numExpectedArgumentNames +
" arguments to bind by name in advice, but actually found " +
@@ -618,7 +620,7 @@ public abstract class AbstractAspectJAdvice implements Advice, AspectJPrecedence
protected Object invokeAdviceMethodWithGivenArgs(Object[] args) throws Throwable {
Object[] actualArgs = args;
if (this.aspectJAdviceMethod.getParameterTypes().length == 0) {
if (this.aspectJAdviceMethod.getParameterCount() == 0) {
actualArgs = null;
}
try {
@@ -5,7 +5,7 @@
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
@@ -1,11 +1,11 @@
/*
* Copyright 2002-2017 the original author or authors.
* Copyright 2002-2016 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.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
@@ -113,7 +113,6 @@ import org.springframework.util.StringUtils;
* returning {@code null} in the case that the parameter names cannot be discovered.
*
* @author Adrian Colyer
* @author Juergen Hoeller
* @since 2.0
*/
public class AspectJAdviceParameterNameDiscoverer implements ParameterNameDiscoverer {
@@ -131,8 +130,8 @@ public class AspectJAdviceParameterNameDiscoverer implements ParameterNameDiscov
private static final int STEP_REFERENCE_PCUT_BINDING = 7;
private static final int STEP_FINISHED = 8;
private static final Set<String> singleValuedAnnotationPcds = new HashSet<String>();
private static final Set<String> nonReferencePointcutTokens = new HashSet<String>();
private static final Set<String> singleValuedAnnotationPcds = new HashSet<>();
private static final Set<String> nonReferencePointcutTokens = new HashSet<>();
static {
@@ -155,17 +154,23 @@ public class AspectJAdviceParameterNameDiscoverer implements ParameterNameDiscov
}
/** The pointcut expression associated with the advice, as a simple String */
private String pointcutExpression;
private boolean raiseExceptions;
/** If the advice is afterReturning, and binds the return value, this is the parameter name used */
/**
* If the advice is afterReturning, and binds the return value, this is the parameter name used.
*/
private String returningName;
/** If the advice is afterThrowing, and binds the thrown value, this is the parameter name used */
/**
* If the advice is afterThrowing, and binds the thrown value, this is the parameter name used.
*/
private String throwingName;
/**
* The pointcut expression associated with the advice, as a simple String.
*/
private String pointcutExpression;
private Class<?>[] argumentTypes;
private String[] parameterNameBindings;
@@ -181,7 +186,6 @@ public class AspectJAdviceParameterNameDiscoverer implements ParameterNameDiscov
this.pointcutExpression = pointcutExpression;
}
/**
* Indicate whether {@link IllegalArgumentException} and {@link AmbiguousBindingException}
* must be thrown as appropriate in the case of failing to deduce advice parameter names.
@@ -209,7 +213,6 @@ public class AspectJAdviceParameterNameDiscoverer implements ParameterNameDiscov
this.throwingName = throwingName;
}
/**
* Deduce the parameter names for an advice method.
* <p>See the {@link AspectJAdviceParameterNameDiscoverer class level javadoc}
@@ -411,11 +414,11 @@ public class AspectJAdviceParameterNameDiscoverer implements ParameterNameDiscov
* <p>Some more support from AspectJ in doing this exercise would be nice... :)
*/
private void maybeBindAnnotationsFromPointcutExpression() {
List<String> varNames = new ArrayList<String>();
List<String> varNames = new ArrayList<>();
String[] tokens = StringUtils.tokenizeToStringArray(this.pointcutExpression, " ");
for (int i = 0; i < tokens.length; i++) {
String toMatch = tokens[i];
int firstParenIndex = toMatch.indexOf('(');
int firstParenIndex = toMatch.indexOf("(");
if (firstParenIndex != -1) {
toMatch = toMatch.substring(0, firstParenIndex);
}
@@ -471,7 +474,7 @@ public class AspectJAdviceParameterNameDiscoverer implements ParameterNameDiscov
* If the token starts meets Java identifier conventions, it's in.
*/
private String maybeExtractVariableName(String candidateToken) {
if (!StringUtils.hasLength(candidateToken)) {
if (candidateToken == null || candidateToken.equals("")) {
return null;
}
if (Character.isJavaIdentifierStart(candidateToken.charAt(0)) &&
@@ -517,7 +520,7 @@ public class AspectJAdviceParameterNameDiscoverer implements ParameterNameDiscov
+ " unbound args at this(),target(),args() binding stage, with no way to determine between them");
}
List<String> varNames = new ArrayList<String>();
List<String> varNames = new ArrayList<>();
String[] tokens = StringUtils.tokenizeToStringArray(this.pointcutExpression, " ");
for (int i = 0; i < tokens.length; i++) {
if (tokens[i].equals("this") ||
@@ -534,7 +537,7 @@ public class AspectJAdviceParameterNameDiscoverer implements ParameterNameDiscov
else if (tokens[i].equals("args") || tokens[i].startsWith("args(")) {
PointcutBody body = getPointcutBody(tokens, i);
i += body.numTokensConsumed;
List<String> candidateVarNames = new ArrayList<String>();
List<String> candidateVarNames = new ArrayList<>();
maybeExtractVariableNamesFromArgs(body.text, candidateVarNames);
// we may have found some var names that were bound in previous primitive args binding step,
// filter them out...
@@ -568,14 +571,14 @@ public class AspectJAdviceParameterNameDiscoverer implements ParameterNameDiscov
+ " unbound args at reference pointcut binding stage, with no way to determine between them");
}
List<String> varNames = new ArrayList<String>();
List<String> varNames = new ArrayList<>();
String[] tokens = StringUtils.tokenizeToStringArray(this.pointcutExpression, " ");
for (int i = 0; i < tokens.length; i++) {
String toMatch = tokens[i];
if (toMatch.startsWith("!")) {
toMatch = toMatch.substring(1);
}
int firstParenIndex = toMatch.indexOf('(');
int firstParenIndex = toMatch.indexOf("(");
if (firstParenIndex != -1) {
toMatch = toMatch.substring(0, firstParenIndex);
}
@@ -649,7 +652,7 @@ public class AspectJAdviceParameterNameDiscoverer implements ParameterNameDiscov
}
if (tokens[currentIndex].endsWith(")")) {
sb.append(tokens[currentIndex], 0, tokens[currentIndex].length() - 1);
sb.append(tokens[currentIndex].substring(0, tokens[currentIndex].length() - 1));
return new PointcutBody(numTokensConsumed, sb.toString().trim());
}
@@ -680,7 +683,7 @@ public class AspectJAdviceParameterNameDiscoverer implements ParameterNameDiscov
}
if (numUnboundPrimitives == 1) {
// Look for arg variable and bind it if we find exactly one...
List<String> varNames = new ArrayList<String>();
List<String> varNames = new ArrayList<>();
String[] tokens = StringUtils.tokenizeToStringArray(this.pointcutExpression, " ");
for (int i = 0; i < tokens.length; i++) {
if (tokens[i].equals("args") || tokens[i].startsWith("args(")) {
@@ -5,7 +5,7 @@
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
@@ -5,7 +5,7 @@
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
@@ -5,7 +5,7 @@
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
@@ -5,7 +5,7 @@
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
@@ -5,7 +5,7 @@
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
@@ -5,7 +5,7 @@
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
@@ -28,6 +28,7 @@ import java.util.concurrent.ConcurrentHashMap;
import org.aopalliance.intercept.MethodInvocation;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.aspectj.weaver.BCException;
import org.aspectj.weaver.patterns.NamePattern;
import org.aspectj.weaver.reflect.ReflectionWorld.ReflectionWorldException;
import org.aspectj.weaver.reflect.ShadowMatchImpl;
@@ -54,6 +55,7 @@ import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.BeanFactoryAware;
import org.springframework.beans.factory.BeanFactoryUtils;
import org.springframework.beans.factory.FactoryBean;
import org.springframework.beans.factory.annotation.BeanFactoryAnnotationUtils;
import org.springframework.beans.factory.config.ConfigurableBeanFactory;
import org.springframework.util.ClassUtils;
import org.springframework.util.ObjectUtils;
@@ -81,7 +83,7 @@ import org.springframework.util.StringUtils;
public class AspectJExpressionPointcut extends AbstractExpressionPointcut
implements ClassFilter, IntroductionAwareMethodMatcher, BeanFactoryAware {
private static final Set<PointcutPrimitive> SUPPORTED_PRIMITIVES = new HashSet<PointcutPrimitive>();
private static final Set<PointcutPrimitive> SUPPORTED_PRIMITIVES = new HashSet<>();
static {
SUPPORTED_PRIMITIVES.add(PointcutPrimitive.EXECUTION);
@@ -111,7 +113,7 @@ public class AspectJExpressionPointcut extends AbstractExpressionPointcut
private transient PointcutExpression pointcutExpression;
private transient Map<Method, ShadowMatch> shadowMatchCache = new ConcurrentHashMap<Method, ShadowMatch>(32);
private transient Map<Method, ShadowMatch> shadowMatchCache = new ConcurrentHashMap<>(32);
/**
@@ -186,24 +188,13 @@ public class AspectJExpressionPointcut extends AbstractExpressionPointcut
throw new IllegalStateException("Must set property 'expression' before attempting to match");
}
if (this.pointcutExpression == null) {
this.pointcutClassLoader = determinePointcutClassLoader();
this.pointcutClassLoader = (this.beanFactory instanceof ConfigurableBeanFactory ?
((ConfigurableBeanFactory) this.beanFactory).getBeanClassLoader() :
ClassUtils.getDefaultClassLoader());
this.pointcutExpression = buildPointcutExpression(this.pointcutClassLoader);
}
}
/**
* Determine the ClassLoader to use for pointcut evaluation.
*/
private ClassLoader determinePointcutClassLoader() {
if (this.beanFactory instanceof ConfigurableBeanFactory) {
return ((ConfigurableBeanFactory) this.beanFactory).getBeanClassLoader();
}
if (this.pointcutDeclarationScope != null) {
return this.pointcutDeclarationScope.getClassLoader();
}
return ClassUtils.getDefaultClassLoader();
}
/**
* Build the underlying AspectJ pointcut expression.
*/
@@ -225,7 +216,7 @@ public class AspectJExpressionPointcut extends AbstractExpressionPointcut
PointcutParser parser = PointcutParser
.getPointcutParserSupportingSpecifiedPrimitivesAndUsingSpecifiedClassLoaderForResolution(
SUPPORTED_PRIMITIVES, cl);
parser.registerPointcutDesignatorHandler(new BeanNamePointcutDesignatorHandler());
parser.registerPointcutDesignatorHandler(new BeanPointcutDesignatorHandler());
return parser;
}
@@ -268,7 +259,7 @@ public class AspectJExpressionPointcut extends AbstractExpressionPointcut
}
}
}
catch (Throwable ex) {
catch (BCException ex) {
logger.debug("PointcutExpression matching rejected target class", ex);
}
return false;
@@ -336,6 +327,7 @@ public class AspectJExpressionPointcut extends AbstractExpressionPointcut
}
catch (IllegalStateException ex) {
// No current invocation...
// TODO: Should we really proceed here?
if (logger.isDebugEnabled()) {
logger.debug("Could not access current invocation - matching with limited context: " + ex);
}
@@ -422,46 +414,39 @@ public class AspectJExpressionPointcut extends AbstractExpressionPointcut
shadowMatch = this.shadowMatchCache.get(targetMethod);
if (shadowMatch == null) {
try {
shadowMatch = this.pointcutExpression.matchesMethodExecution(methodToMatch);
}
catch (ReflectionWorldException ex) {
// Failed to introspect target method, probably because it has been loaded
// in a special ClassLoader. Let's try the declaring ClassLoader instead...
try {
fallbackExpression = getFallbackPointcutExpression(methodToMatch.getDeclaringClass());
if (fallbackExpression != null) {
shadowMatch = fallbackExpression.matchesMethodExecution(methodToMatch);
}
}
catch (ReflectionWorldException ex2) {
fallbackExpression = null;
}
}
if (shadowMatch == null && targetMethod != originalMethod) {
methodToMatch = originalMethod;
try {
shadowMatch = this.pointcutExpression.matchesMethodExecution(methodToMatch);
}
catch (ReflectionWorldException ex) {
// Failed to introspect target method, probably because it has been loaded
// in a special ClassLoader. Let's try the declaring ClassLoader instead...
catch (ReflectionWorldException ex3) {
// Could neither introspect the target class nor the proxy class ->
// let's try the original method's declaring class before we give up...
try {
fallbackExpression = getFallbackPointcutExpression(methodToMatch.getDeclaringClass());
if (fallbackExpression != null) {
shadowMatch = fallbackExpression.matchesMethodExecution(methodToMatch);
}
}
catch (ReflectionWorldException ex2) {
catch (ReflectionWorldException ex4) {
fallbackExpression = null;
}
}
if (shadowMatch == null && targetMethod != originalMethod) {
methodToMatch = originalMethod;
try {
shadowMatch = this.pointcutExpression.matchesMethodExecution(methodToMatch);
}
catch (ReflectionWorldException ex3) {
// Could neither introspect the target class nor the proxy class ->
// let's try the original method's declaring class before we give up...
try {
fallbackExpression = getFallbackPointcutExpression(methodToMatch.getDeclaringClass());
if (fallbackExpression != null) {
shadowMatch = fallbackExpression.matchesMethodExecution(methodToMatch);
}
}
catch (ReflectionWorldException ex4) {
fallbackExpression = null;
}
}
}
}
catch (Throwable ex) {
// Possibly AspectJ 1.8.10 encountering an invalid signature
logger.debug("PointcutExpression matching rejected target method", ex);
fallbackExpression = null;
}
if (shadowMatch == null) {
shadowMatch = new ShadowMatchImpl(org.aspectj.util.FuzzyBoolean.NO, null, null, null);
@@ -537,7 +522,7 @@ public class AspectJExpressionPointcut extends AbstractExpressionPointcut
* automatically by examining a thread local variable and therefore a matching
* context need not be set on the pointcut.
*/
private class BeanNamePointcutDesignatorHandler implements PointcutDesignatorHandler {
private class BeanPointcutDesignatorHandler implements PointcutDesignatorHandler {
private static final String BEAN_DESIGNATOR_NAME = "bean";
@@ -548,7 +533,7 @@ public class AspectJExpressionPointcut extends AbstractExpressionPointcut
@Override
public ContextBasedMatcher parse(String expression) {
return new BeanNameContextMatcher(expression);
return new BeanContextMatcher(expression);
}
}
@@ -560,11 +545,11 @@ public class AspectJExpressionPointcut extends AbstractExpressionPointcut
* For static match tests, this matcher abstains to allow the overall
* pointcut to match even when negation is used with the bean() pointcut.
*/
private class BeanNameContextMatcher implements ContextBasedMatcher {
private class BeanContextMatcher implements ContextBasedMatcher {
private final NamePattern expressionPattern;
public BeanNameContextMatcher(String expression) {
public BeanContextMatcher(String expression) {
this.expressionPattern = new NamePattern(expression);
}
@@ -609,27 +594,16 @@ public class AspectJExpressionPointcut extends AbstractExpressionPointcut
if (targetType != null) {
boolean isFactory = FactoryBean.class.isAssignableFrom(targetType);
return FuzzyBoolean.fromBoolean(
matchesBeanName(isFactory ? BeanFactory.FACTORY_BEAN_PREFIX + advisedBeanName : advisedBeanName));
matchesBean(isFactory ? BeanFactory.FACTORY_BEAN_PREFIX + advisedBeanName : advisedBeanName));
}
else {
return FuzzyBoolean.fromBoolean(matchesBeanName(advisedBeanName) ||
matchesBeanName(BeanFactory.FACTORY_BEAN_PREFIX + advisedBeanName));
return FuzzyBoolean.fromBoolean(matchesBean(advisedBeanName) ||
matchesBean(BeanFactory.FACTORY_BEAN_PREFIX + advisedBeanName));
}
}
private boolean matchesBeanName(String advisedBeanName) {
if (this.expressionPattern.matches(advisedBeanName)) {
return true;
}
if (beanFactory != null) {
String[] aliases = beanFactory.getAliases(advisedBeanName);
for (String alias : aliases) {
if (this.expressionPattern.matches(alias)) {
return true;
}
}
}
return false;
private boolean matchesBean(String advisedBeanName) {
return BeanFactoryAnnotationUtils.isQualifierMatch(this.expressionPattern::matches, advisedBeanName, beanFactory);
}
}
@@ -644,7 +618,7 @@ public class AspectJExpressionPointcut extends AbstractExpressionPointcut
// Initialize transient fields.
// pointcutExpression will be initialized lazily by checkReadyToMatch()
this.shadowMatchCache = new ConcurrentHashMap<Method, ShadowMatch>(32);
this.shadowMatchCache = new ConcurrentHashMap<>(32);
}
@@ -1,11 +1,11 @@
/*
* Copyright 2002-2016 the original author or authors.
* Copyright 2002-2014 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.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
@@ -18,8 +18,6 @@ package org.springframework.aop.aspectj;
import org.springframework.aop.Pointcut;
import org.springframework.aop.support.AbstractGenericPointcutAdvisor;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.BeanFactoryAware;
/**
* Spring AOP Advisor that can be used for any AspectJ pointcut expression.
@@ -28,11 +26,16 @@ import org.springframework.beans.factory.BeanFactoryAware;
* @since 2.0
*/
@SuppressWarnings("serial")
public class AspectJExpressionPointcutAdvisor extends AbstractGenericPointcutAdvisor implements BeanFactoryAware {
public class AspectJExpressionPointcutAdvisor extends AbstractGenericPointcutAdvisor {
private final AspectJExpressionPointcut pointcut = new AspectJExpressionPointcut();
@Override
public Pointcut getPointcut() {
return this.pointcut;
}
public void setExpression(String expression) {
this.pointcut.setExpression(expression);
}
@@ -49,22 +52,12 @@ public class AspectJExpressionPointcutAdvisor extends AbstractGenericPointcutAdv
return this.pointcut.getLocation();
}
public void setParameterTypes(Class<?>[] types) {
this.pointcut.setParameterTypes(types);
}
public void setParameterNames(String... names) {
this.pointcut.setParameterNames(names);
}
public void setParameterTypes(Class<?>... types) {
this.pointcut.setParameterTypes(types);
}
@Override
public void setBeanFactory(BeanFactory beanFactory) {
this.pointcut.setBeanFactory(beanFactory);
}
@Override
public Pointcut getPointcut() {
return this.pointcut;
}
}
@@ -5,7 +5,7 @@
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
@@ -1,11 +1,11 @@
/*
* Copyright 2002-2017 the original author or authors.
* Copyright 2002-2012 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.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
@@ -22,6 +22,7 @@ import org.springframework.aop.Pointcut;
import org.springframework.aop.PointcutAdvisor;
import org.springframework.core.Ordered;
import org.springframework.util.Assert;
import org.springframework.util.ObjectUtils;
/**
* AspectJPointcutAdvisor that adapts an {@link AbstractAspectJAdvice}
@@ -50,11 +51,11 @@ public class AspectJPointcutAdvisor implements PointcutAdvisor, Ordered {
this.pointcut = advice.buildSafePointcut();
}
public void setOrder(int order) {
this.order = order;
}
@Override
public boolean isPerInstance() {
return true;
@@ -90,12 +91,12 @@ public class AspectJPointcutAdvisor implements PointcutAdvisor, Ordered {
return false;
}
AspectJPointcutAdvisor otherAdvisor = (AspectJPointcutAdvisor) other;
return this.advice.equals(otherAdvisor.advice);
return (ObjectUtils.nullSafeEquals(this.advice, otherAdvisor.advice));
}
@Override
public int hashCode() {
return AspectJPointcutAdvisor.class.hashCode() * 29 + this.advice.hashCode();
return AspectJPointcutAdvisor.class.hashCode();
}
}
@@ -5,7 +5,7 @@
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
@@ -5,7 +5,7 @@
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
@@ -5,7 +5,7 @@
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
@@ -1,11 +1,11 @@
/*
* Copyright 2002-2018 the original author or authors.
* Copyright 2002-2012 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.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
@@ -20,7 +20,6 @@ import org.aopalliance.aop.Advice;
import org.springframework.aop.ClassFilter;
import org.springframework.aop.IntroductionAdvisor;
import org.springframework.aop.IntroductionInterceptor;
import org.springframework.aop.support.ClassFilters;
import org.springframework.aop.support.DelegatePerTargetObjectIntroductionInterceptor;
import org.springframework.aop.support.DelegatingIntroductionInterceptor;
@@ -35,12 +34,12 @@ import org.springframework.aop.support.DelegatingIntroductionInterceptor;
*/
public class DeclareParentsAdvisor implements IntroductionAdvisor {
private final Advice advice;
private final Class<?> introducedInterface;
private final ClassFilter typePatternClassFilter;
private final Advice advice;
/**
* Create a new advisor for this DeclareParents field.
@@ -49,8 +48,8 @@ public class DeclareParentsAdvisor implements IntroductionAdvisor {
* @param defaultImpl the default implementation class
*/
public DeclareParentsAdvisor(Class<?> interfaceType, String typePattern, Class<?> defaultImpl) {
this(interfaceType, typePattern,
new DelegatePerTargetObjectIntroductionInterceptor(defaultImpl, interfaceType));
this(interfaceType, typePattern, defaultImpl,
new DelegatePerTargetObjectIntroductionInterceptor(defaultImpl, interfaceType));
}
/**
@@ -60,7 +59,8 @@ public class DeclareParentsAdvisor implements IntroductionAdvisor {
* @param delegateRef the delegate implementation object
*/
public DeclareParentsAdvisor(Class<?> interfaceType, String typePattern, Object delegateRef) {
this(interfaceType, typePattern, new DelegatingIntroductionInterceptor(delegateRef));
this(interfaceType, typePattern, delegateRef.getClass(),
new DelegatingIntroductionInterceptor(delegateRef));
}
/**
@@ -68,21 +68,23 @@ public class DeclareParentsAdvisor implements IntroductionAdvisor {
* (cannot use method such as init() to share common code, due the use of final fields)
* @param interfaceType static field defining the introduction
* @param typePattern type pattern the introduction is restricted to
* @param interceptor the delegation advice as {@link IntroductionInterceptor}
* @param implementationClass implementation class
* @param advice delegation advice
*/
private DeclareParentsAdvisor(Class<?> interfaceType, String typePattern, IntroductionInterceptor interceptor) {
this.advice = interceptor;
private DeclareParentsAdvisor(Class<?> interfaceType, String typePattern, Class<?> implementationClass, Advice advice) {
this.introducedInterface = interfaceType;
ClassFilter typePatternFilter = new TypePatternClassFilter(typePattern);
// Excludes methods implemented.
ClassFilter typePatternFilter = new TypePatternClassFilter(typePattern);
ClassFilter exclusion = new ClassFilter() {
@Override
public boolean matches(Class<?> clazz) {
return !introducedInterface.isAssignableFrom(clazz);
return !(introducedInterface.isAssignableFrom(clazz));
}
};
this.typePatternClassFilter = ClassFilters.intersection(typePatternFilter, exclusion);
this.advice = advice;
}
@@ -5,7 +5,7 @@
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
@@ -1,11 +1,11 @@
/*
* Copyright 2002-2020 the original author or authors.
* Copyright 2002-2015 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.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
@@ -32,15 +32,17 @@ import org.springframework.core.ParameterNameDiscoverer;
import org.springframework.util.Assert;
/**
* An implementation of the AspectJ {@link ProceedingJoinPoint} interface
* wrapping an AOP Alliance {@link org.aopalliance.intercept.MethodInvocation}.
* Implementation of AspectJ ProceedingJoinPoint interface
* wrapping an AOP Alliance MethodInvocation.
*
* <p><b>Note</b>: The {@code getThis()} method returns the current Spring AOP proxy.
* <p><b>Note</b>: the {@code getThis()} method returns the current Spring AOP proxy.
* The {@code getTarget()} method returns the current Spring AOP target (which may be
* {@code null} if there is no target instance) as a plain POJO without any advice.
* <b>If you want to call the object and have the advice take effect, use {@code getThis()}.</b>
* A common example is casting the object to an introduced interface in the implementation of
* an introduction. There is no such distinction between target and proxy in AspectJ itself.
* {@code null} if there is no target), and is a plain POJO without any advice.
* <b>If you want to call the object and have the advice take effect, use
* {@code getThis()}.</b> A common example is casting the object to an
* introduced interface in the implementation of an introduction.
*
* <p>Of course there is no such distinction between target and proxy in AspectJ.
*
* @author Rod Johnson
* @author Juergen Hoeller
@@ -54,7 +56,7 @@ public class MethodInvocationProceedingJoinPoint implements ProceedingJoinPoint,
private final ProxyMethodInvocation methodInvocation;
private Object[] args;
private Object[] defensiveCopyOfArgs;
/** Lazily initialized signature object */
private Signature signature;
@@ -73,7 +75,6 @@ public class MethodInvocationProceedingJoinPoint implements ProceedingJoinPoint,
this.methodInvocation = methodInvocation;
}
@Override
public void set$AroundClosure(AroundClosure aroundClosure) {
throw new UnsupportedOperationException();
@@ -114,10 +115,12 @@ public class MethodInvocationProceedingJoinPoint implements ProceedingJoinPoint,
@Override
public Object[] getArgs() {
if (this.args == null) {
this.args = this.methodInvocation.getArguments().clone();
if (this.defensiveCopyOfArgs == null) {
Object[] argsSource = this.methodInvocation.getArguments();
this.defensiveCopyOfArgs = new Object[argsSource.length];
System.arraycopy(argsSource, 0, this.defensiveCopyOfArgs, 0, argsSource.length);
}
return this.args;
return this.defensiveCopyOfArgs;
}
@Override
@@ -125,7 +128,7 @@ public class MethodInvocationProceedingJoinPoint implements ProceedingJoinPoint,
if (this.signature == null) {
this.signature = new MethodSignatureImpl();
}
return this.signature;
return signature;
}
@Override
@@ -212,12 +215,10 @@ public class MethodInvocationProceedingJoinPoint implements ProceedingJoinPoint,
@Override
public String[] getParameterNames() {
String[] parameterNames = this.parameterNames;
if (parameterNames == null) {
parameterNames = parameterNameDiscoverer.getParameterNames(getMethod());
this.parameterNames = parameterNames;
if (this.parameterNames == null) {
this.parameterNames = parameterNameDiscoverer.getParameterNames(getMethod());
}
return parameterNames;
return this.parameterNames;
}
@Override
@@ -5,7 +5,7 @@
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
@@ -1,11 +1,11 @@
/*
* Copyright 2002-2018 the original author or authors.
* Copyright 2002-2016 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.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
@@ -16,9 +16,12 @@
package org.springframework.aop.aspectj;
import java.lang.reflect.InvocationTargetException;
import org.springframework.aop.framework.AopConfigException;
import org.springframework.core.Ordered;
import org.springframework.util.Assert;
import org.springframework.util.ReflectionUtils;
/**
* Implementation of {@link AspectInstanceFactory} that creates a new instance
@@ -41,7 +44,6 @@ public class SimpleAspectInstanceFactory implements AspectInstanceFactory {
this.aspectClass = aspectClass;
}
/**
* Return the specified aspect class (never {@code null}).
*/
@@ -49,10 +51,15 @@ public class SimpleAspectInstanceFactory implements AspectInstanceFactory {
return this.aspectClass;
}
@Override
public final Object getAspectInstance() {
try {
return this.aspectClass.newInstance();
return ReflectionUtils.accessibleConstructor(this.aspectClass).newInstance();
}
catch (NoSuchMethodException ex) {
throw new AopConfigException(
"No default constructor on aspect class: " + this.aspectClass.getName(), ex);
}
catch (InstantiationException ex) {
throw new AopConfigException(
@@ -62,6 +69,10 @@ public class SimpleAspectInstanceFactory implements AspectInstanceFactory {
throw new AopConfigException(
"Could not access aspect constructor: " + this.aspectClass.getName(), ex);
}
catch (InvocationTargetException ex) {
throw new AopConfigException(
"Failed to invoke aspect constructor: " + this.aspectClass.getName(), ex.getTargetException());
}
}
@Override
@@ -5,7 +5,7 @@
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
@@ -1,11 +1,11 @@
/*
* Copyright 2002-2017 the original author or authors.
* Copyright 2002-2012 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.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
@@ -27,7 +27,6 @@ import org.springframework.util.StringUtils;
* Spring AOP {@link ClassFilter} implementation using AspectJ type matching.
*
* @author Rod Johnson
* @author Juergen Hoeller
* @since 2.0
*/
public class TypePatternClassFilter implements ClassFilter {
@@ -77,21 +76,17 @@ public class TypePatternClassFilter implements ClassFilter {
* or is recognized as invalid
*/
public void setTypePattern(String typePattern) {
Assert.notNull(typePattern, "Type pattern must not be null");
Assert.notNull(typePattern);
this.typePattern = typePattern;
this.aspectJTypePatternMatcher =
PointcutParser.getPointcutParserSupportingAllPrimitivesAndUsingContextClassloaderForResolution().
parseTypePattern(replaceBooleanOperators(typePattern));
}
/**
* Return the AspectJ type pattern to match.
*/
public String getTypePattern() {
return this.typePattern;
return typePattern;
}
/**
* Should the pointcut apply to the given interface or target class?
* @param clazz candidate target class
@@ -100,7 +95,9 @@ public class TypePatternClassFilter implements ClassFilter {
*/
@Override
public boolean matches(Class<?> clazz) {
Assert.state(this.aspectJTypePatternMatcher != null, "No type pattern has been set");
if (this.aspectJTypePatternMatcher == null) {
throw new IllegalStateException("No 'typePattern' has been set via ctor/setter.");
}
return this.aspectJTypePatternMatcher.matches(clazz);
}
@@ -111,8 +108,9 @@ public class TypePatternClassFilter implements ClassFilter {
* <p>This method converts back to {@code &&} for the AspectJ pointcut parser.
*/
private String replaceBooleanOperators(String pcExpr) {
String result = StringUtils.replace(pcExpr," and "," && ");
result = StringUtils.replace(result, " or ", " || ");
return StringUtils.replace(result, " not ", " ! ");
pcExpr = StringUtils.replace(pcExpr," and "," && ");
pcExpr = StringUtils.replace(pcExpr, " or ", " || ");
pcExpr = StringUtils.replace(pcExpr, " not ", " ! ");
return pcExpr;
}
}
@@ -1,11 +1,11 @@
/*
* Copyright 2002-2018 the original author or authors.
* Copyright 2002-2016 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.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
@@ -38,6 +38,7 @@ import org.aspectj.lang.reflect.AjType;
import org.aspectj.lang.reflect.AjTypeSystem;
import org.aspectj.lang.reflect.PerClauseKind;
import org.springframework.aop.aspectj.AspectJExpressionPointcut;
import org.springframework.aop.framework.AopConfigException;
import org.springframework.core.ParameterNameDiscoverer;
import org.springframework.core.annotation.AnnotationUtils;
@@ -59,9 +60,6 @@ public abstract class AbstractAspectJAdvisorFactory implements AspectJAdvisorFac
private static final String AJC_MAGIC = "ajc$";
private static final Class<?>[] ASPECTJ_ANNOTATION_CLASSES = new Class<?>[] {
Pointcut.class, Around.class, Before.class, After.class, AfterReturning.class, AfterThrowing.class};
/** Logger available to subclasses */
protected final Log logger = LogFactory.getLog(getClass());
@@ -123,14 +121,59 @@ public abstract class AbstractAspectJAdvisorFactory implements AspectJAdvisorFac
}
}
/**
* The pointcut and advice annotations both have an "argNames" member which contains a
* comma-separated list of the argument names. We use this (if non-empty) to build the
* formal parameters for the pointcut.
*/
protected AspectJExpressionPointcut createPointcutExpression(
Method annotatedMethod, Class<?> declarationScope, String[] pointcutParameterNames) {
Class<?> [] pointcutParameterTypes = new Class<?>[0];
if (pointcutParameterNames != null) {
pointcutParameterTypes = extractPointcutParameterTypes(pointcutParameterNames,annotatedMethod);
}
AspectJExpressionPointcut ajexp =
new AspectJExpressionPointcut(declarationScope,pointcutParameterNames,pointcutParameterTypes);
ajexp.setLocation(annotatedMethod.toString());
return ajexp;
}
/**
* Create the pointcut parameters needed by aspectj based on the given argument names
* and the argument types that are available from the adviceMethod. Needs to take into
* account (ignore) any JoinPoint based arguments as these are not pointcut context but
* rather part of the advice execution context (thisJoinPoint, thisJoinPointStaticPart)
*/
private Class<?>[] extractPointcutParameterTypes(String[] argNames, Method adviceMethod) {
Class<?>[] ret = new Class<?>[argNames.length];
Class<?>[] paramTypes = adviceMethod.getParameterTypes();
if (argNames.length > paramTypes.length) {
throw new IllegalStateException("Expecting at least " + argNames.length +
" arguments in the advice declaration, but only found " + paramTypes.length);
}
// Make the simplifying assumption for now that all of the JoinPoint based arguments
// come first in the advice declaration.
int typeOffset = paramTypes.length - argNames.length;
for (int i = 0; i < ret.length; i++) {
ret[i] = paramTypes[i + typeOffset];
}
return ret;
}
/**
* Find and return the first AspectJ annotation on the given method
* (there <i>should</i> only be one anyway...).
* (there <i>should</i> only be one anyway...)
*/
@SuppressWarnings("unchecked")
protected static AspectJAnnotation<?> findAspectJAnnotationOnMethod(Method method) {
for (Class<?> clazz : ASPECTJ_ANNOTATION_CLASSES) {
AspectJAnnotation<?> foundAnnotation = findAnnotation(method, (Class<Annotation>) clazz);
Class<?>[] classesToLookFor = new Class<?>[] {
Before.class, Around.class, After.class, AfterReturning.class, AfterThrowing.class, Pointcut.class};
for (Class<?> c : classesToLookFor) {
AspectJAnnotation<?> foundAnnotation = findAnnotation(method, (Class<Annotation>) c);
if (foundAnnotation != null) {
return foundAnnotation;
}
@@ -141,7 +184,7 @@ public abstract class AbstractAspectJAdvisorFactory implements AspectJAdvisorFac
private static <A extends Annotation> AspectJAnnotation<A> findAnnotation(Method method, Class<A> toLookFor) {
A result = AnnotationUtils.findAnnotation(method, toLookFor);
if (result != null) {
return new AspectJAnnotation<A>(result);
return new AspectJAnnotation<>(result);
}
else {
return null;
@@ -149,13 +192,14 @@ public abstract class AbstractAspectJAdvisorFactory implements AspectJAdvisorFac
}
/**
* Enum for AspectJ annotation types.
* @see AspectJAnnotation#getAnnotationType()
*/
protected enum AspectJAnnotationType {
AtPointcut, AtAround, AtBefore, AtAfter, AtAfterReturning, AtAfterThrowing
AtPointcut,
AtBefore,
AtAfter,
AtAfterReturning,
AtAfterThrowing,
AtAround
}
@@ -165,18 +209,18 @@ public abstract class AbstractAspectJAdvisorFactory implements AspectJAdvisorFac
*/
protected static class AspectJAnnotation<A extends Annotation> {
private static final String[] EXPRESSION_ATTRIBUTES = new String[] {"pointcut", "value"};
private static final String[] EXPRESSION_PROPERTIES = new String[] {"value", "pointcut"};
private static Map<Class<?>, AspectJAnnotationType> annotationTypeMap =
new HashMap<Class<?>, AspectJAnnotationType>(8);
private static Map<Class<?>, AspectJAnnotationType> annotationTypes =
new HashMap<>();
static {
annotationTypeMap.put(Pointcut.class, AspectJAnnotationType.AtPointcut);
annotationTypeMap.put(Around.class, AspectJAnnotationType.AtAround);
annotationTypeMap.put(Before.class, AspectJAnnotationType.AtBefore);
annotationTypeMap.put(After.class, AspectJAnnotationType.AtAfter);
annotationTypeMap.put(AfterReturning.class, AspectJAnnotationType.AtAfterReturning);
annotationTypeMap.put(AfterThrowing.class, AspectJAnnotationType.AtAfterThrowing);
annotationTypes.put(Pointcut.class,AspectJAnnotationType.AtPointcut);
annotationTypes.put(After.class,AspectJAnnotationType.AtAfter);
annotationTypes.put(AfterReturning.class,AspectJAnnotationType.AtAfterReturning);
annotationTypes.put(AfterThrowing.class,AspectJAnnotationType.AtAfterThrowing);
annotationTypes.put(Around.class,AspectJAnnotationType.AtAround);
annotationTypes.put(Before.class,AspectJAnnotationType.AtBefore);
}
private final A annotation;
@@ -190,31 +234,44 @@ public abstract class AbstractAspectJAdvisorFactory implements AspectJAdvisorFac
public AspectJAnnotation(A annotation) {
this.annotation = annotation;
this.annotationType = determineAnnotationType(annotation);
// We know these methods exist with the same name on each object,
// but need to invoke them reflectively as there isn't a common interface.
try {
this.pointcutExpression = resolveExpression(annotation);
this.argumentNames = (String) AnnotationUtils.getValue(annotation, "argNames");
this.argumentNames = (String) annotation.getClass().getMethod("argNames").invoke(annotation);
}
catch (Exception ex) {
throw new IllegalArgumentException(annotation + " is not a valid AspectJ annotation", ex);
throw new IllegalArgumentException(annotation + " cannot be an AspectJ annotation", ex);
}
}
private AspectJAnnotationType determineAnnotationType(A annotation) {
AspectJAnnotationType type = annotationTypeMap.get(annotation.annotationType());
if (type != null) {
return type;
}
throw new IllegalStateException("Unknown annotation type: " + annotation);
}
private String resolveExpression(A annotation) {
for (String attributeName : EXPRESSION_ATTRIBUTES) {
String candidate = (String) AnnotationUtils.getValue(annotation, attributeName);
if (StringUtils.hasText(candidate)) {
return candidate;
for (Class<?> type : annotationTypes.keySet()) {
if (type.isInstance(annotation)) {
return annotationTypes.get(type);
}
}
throw new IllegalStateException("Failed to resolve expression: " + annotation);
throw new IllegalStateException("Unknown annotation type: " + annotation.toString());
}
private String resolveExpression(A annotation) throws Exception {
String expression = null;
for (String methodName : EXPRESSION_PROPERTIES) {
Method method;
try {
method = annotation.getClass().getDeclaredMethod(methodName);
}
catch (NoSuchMethodException ex) {
method = null;
}
if (method != null) {
String candidate = (String) method.invoke(annotation);
if (StringUtils.hasText(candidate)) {
expression = candidate;
}
}
}
return expression;
}
public AspectJAnnotationType getAnnotationType() {
@@ -248,18 +305,18 @@ public abstract class AbstractAspectJAdvisorFactory implements AspectJAdvisorFac
@Override
public String[] getParameterNames(Method method) {
if (method.getParameterTypes().length == 0) {
if (method.getParameterCount() == 0) {
return new String[0];
}
AspectJAnnotation<?> annotation = findAspectJAnnotationOnMethod(method);
if (annotation == null) {
return null;
}
StringTokenizer nameTokens = new StringTokenizer(annotation.getArgumentNames(), ",");
if (nameTokens.countTokens() > 0) {
String[] names = new String[nameTokens.countTokens()];
StringTokenizer strTok = new StringTokenizer(annotation.getArgumentNames(), ",");
if (strTok.countTokens() > 0) {
String[] names = new String[strTok.countTokens()];
for (int i = 0; i < names.length; i++) {
names[i] = nameTokens.nextToken();
names[i] = strTok.nextToken();
}
return names;
}
@@ -5,7 +5,7 @@
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
@@ -50,7 +50,7 @@ public class AnnotationAwareAspectJAutoProxyCreator extends AspectJAwareAdvisorA
private List<Pattern> includePatterns;
private AspectJAdvisorFactory aspectJAdvisorFactory;
private AspectJAdvisorFactory aspectJAdvisorFactory = new ReflectiveAspectJAdvisorFactory();
private BeanFactoryAspectJAdvisorsBuilder aspectJAdvisorsBuilder;
@@ -60,7 +60,7 @@ public class AnnotationAwareAspectJAutoProxyCreator extends AspectJAwareAdvisorA
* <p>Default is to consider all @AspectJ beans as eligible.
*/
public void setIncludePatterns(List<String> patterns) {
this.includePatterns = new ArrayList<Pattern>(patterns.size());
this.includePatterns = new ArrayList<>(patterns.size());
for (String patternText : patterns) {
this.includePatterns.add(Pattern.compile(patternText));
}
@@ -74,9 +74,6 @@ public class AnnotationAwareAspectJAutoProxyCreator extends AspectJAwareAdvisorA
@Override
protected void initBeanFactory(ConfigurableListableBeanFactory beanFactory) {
super.initBeanFactory(beanFactory);
if (this.aspectJAdvisorFactory == null) {
this.aspectJAdvisorFactory = new ReflectiveAspectJAdvisorFactory(beanFactory);
}
this.aspectJAdvisorsBuilder =
new BeanFactoryAspectJAdvisorsBuilderAdapter(beanFactory, this.aspectJAdvisorFactory);
}
@@ -133,7 +130,6 @@ public class AnnotationAwareAspectJAutoProxyCreator extends AspectJAwareAdvisorA
public BeanFactoryAspectJAdvisorsBuilderAdapter(
ListableBeanFactory beanFactory, AspectJAdvisorFactory advisorFactory) {
super(beanFactory, advisorFactory);
}
@@ -5,7 +5,7 @@
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
@@ -1,11 +1,11 @@
/*
* Copyright 2002-2018 the original author or authors.
* Copyright 2002-2016 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.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
@@ -16,15 +16,15 @@
package org.springframework.aop.aspectj.annotation;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import org.aspectj.lang.reflect.PerClauseKind;
import org.springframework.aop.Advisor;
import org.springframework.aop.aspectj.AspectJProxyUtils;
import org.springframework.aop.framework.AopConfigException;
import org.springframework.aop.aspectj.SimpleAspectInstanceFactory;
import org.springframework.aop.framework.ProxyCreatorSupport;
import org.springframework.aop.support.AopUtils;
import org.springframework.core.annotation.AnnotationAwareOrderComparator;
@@ -50,7 +50,7 @@ import org.springframework.util.ClassUtils;
public class AspectJProxyFactory extends ProxyCreatorSupport {
/** Cache for singleton aspect instances */
private static final Map<Class<?>, Object> aspectCache = new ConcurrentHashMap<Class<?>, Object>();
private static final Map<Class<?>, Object> aspectCache = new HashMap<>();
private final AspectJAdvisorFactory aspectFactory = new ReflectiveAspectJAdvisorFactory();
@@ -144,7 +144,7 @@ public class AspectJProxyFactory extends ProxyCreatorSupport {
private MetadataAwareAspectInstanceFactory createAspectInstanceFactory(
AspectMetadata am, Class<?> aspectClass, String aspectName) {
MetadataAwareAspectInstanceFactory instanceFactory;
MetadataAwareAspectInstanceFactory instanceFactory = null;
if (am.getAjType().getPerClause().getKind() == PerClauseKind.SINGLETON) {
// Create a shared aspect instance.
Object instance = getSingletonAspectInstance(aspectClass);
@@ -162,29 +162,15 @@ public class AspectJProxyFactory extends ProxyCreatorSupport {
* is created if one cannot be found in the instance cache.
*/
private Object getSingletonAspectInstance(Class<?> aspectClass) {
// Quick check without a lock...
Object instance = aspectCache.get(aspectClass);
if (instance == null) {
synchronized (aspectCache) {
// To be safe, check within full lock now...
instance = aspectCache.get(aspectClass);
if (instance == null) {
try {
instance = aspectClass.newInstance();
aspectCache.put(aspectClass, instance);
}
catch (InstantiationException ex) {
throw new AopConfigException(
"Unable to instantiate aspect class: " + aspectClass.getName(), ex);
}
catch (IllegalAccessException ex) {
throw new AopConfigException(
"Could not access aspect constructor: " + aspectClass.getName(), ex);
}
}
synchronized (aspectCache) {
Object instance = aspectCache.get(aspectClass);
if (instance != null) {
return instance;
}
instance = new SimpleAspectInstanceFactory(aspectClass).getAspectInstance();
aspectCache.put(aspectClass, instance);
return instance;
}
return instance;
}
@@ -1,11 +1,11 @@
/*
* Copyright 2002-2016 the original author or authors.
* Copyright 2002-2015 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.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
@@ -35,8 +35,9 @@ import org.springframework.aop.support.ComposablePointcut;
* Metadata for an AspectJ aspect class, with an additional Spring AOP pointcut
* for the per clause.
*
* <p>Uses AspectJ 5 AJType reflection API, enabling us to work with different
* AspectJ instantiation models such as "singleton", "pertarget" and "perthis".
* <p>Uses AspectJ 5 AJType reflection API, so is only supported on Java 5.
* Enables us to work with different AspectJ instantiation models such as
* "singleton", "pertarget" and "perthis".
*
* @author Rod Johnson
* @author Juergen Hoeller
@@ -101,22 +102,20 @@ public class AspectMetadata implements Serializable {
this.ajType = ajType;
switch (this.ajType.getPerClause().getKind()) {
case SINGLETON:
case SINGLETON :
this.perClausePointcut = Pointcut.TRUE;
return;
case PERTARGET:
case PERTHIS:
case PERTARGET : case PERTHIS :
AspectJExpressionPointcut ajexp = new AspectJExpressionPointcut();
ajexp.setLocation(aspectClass.getName());
ajexp.setLocation("@Aspect annotation on " + aspectClass.getName());
ajexp.setExpression(findPerClause(aspectClass));
ajexp.setPointcutDeclarationScope(aspectClass);
this.perClausePointcut = ajexp;
return;
case PERTYPEWITHIN:
case PERTYPEWITHIN :
// Works with a type pattern
this.perClausePointcut = new ComposablePointcut(new TypePatternClassFilter(findPerClause(aspectClass)));
return;
default:
default :
throw new AopConfigException(
"PerClause " + ajType.getPerClause().getKind() + " not supported by Spring AOP for " + aspectClass);
}
@@ -126,8 +125,10 @@ public class AspectMetadata implements Serializable {
* Extract contents from String of form {@code pertarget(contents)}.
*/
private String findPerClause(Class<?> aspectClass) {
// TODO when AspectJ provides this, we can remove this hack. Hence we don't
// bother to make it elegant. Or efficient. Or robust :-)
String str = aspectClass.getAnnotation(Aspect.class).value();
str = str.substring(str.indexOf('(') + 1);
str = str.substring(str.indexOf("(") + 1);
str = str.substring(0, str.length() - 1);
return str;
}
@@ -148,7 +149,7 @@ public class AspectMetadata implements Serializable {
}
/**
* Return the aspect name.
* Return the aspect class.
*/
public String getAspectName() {
return this.aspectName;
@@ -5,7 +5,7 @@
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
@@ -97,19 +97,8 @@ public class BeanFactoryAspectInstanceFactory implements MetadataAwareAspectInst
@Override
public Object getAspectCreationMutex() {
if (this.beanFactory != null) {
if (this.beanFactory.isSingleton(name)) {
// Rely on singleton semantics provided by the factory -> no local lock.
return null;
}
else if (this.beanFactory instanceof ConfigurableBeanFactory) {
// No singleton guarantees from the factory -> let's lock locally but
// reuse the factory's singleton lock, just in case a lazy dependency
// of our advice bean happens to trigger the singleton lock implicitly...
return ((ConfigurableBeanFactory) this.beanFactory).getSingletonMutex();
}
}
return this;
return (this.beanFactory instanceof ConfigurableBeanFactory ?
((ConfigurableBeanFactory) this.beanFactory).getSingletonMutex() : this);
}
/**
@@ -5,7 +5,7 @@
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
@@ -17,10 +17,10 @@
package org.springframework.aop.aspectj.annotation;
import java.util.Collections;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import org.aspectj.lang.reflect.PerClauseKind;
@@ -43,12 +43,12 @@ public class BeanFactoryAspectJAdvisorsBuilder {
private final AspectJAdvisorFactory advisorFactory;
private volatile List<String> aspectBeanNames;
private List<String> aspectBeanNames;
private final Map<String, List<Advisor>> advisorsCache = new ConcurrentHashMap<String, List<Advisor>>();
private final Map<String, List<Advisor>> advisorsCache = new HashMap<>();
private final Map<String, MetadataAwareAspectInstanceFactory> aspectFactoryCache =
new ConcurrentHashMap<String, MetadataAwareAspectInstanceFactory>();
new HashMap<>();
/**
@@ -56,7 +56,7 @@ public class BeanFactoryAspectJAdvisorsBuilder {
* @param beanFactory the ListableBeanFactory to scan
*/
public BeanFactoryAspectJAdvisorsBuilder(ListableBeanFactory beanFactory) {
this(beanFactory, new ReflectiveAspectJAdvisorFactory(beanFactory));
this(beanFactory, new ReflectiveAspectJAdvisorFactory());
}
/**
@@ -80,64 +80,63 @@ public class BeanFactoryAspectJAdvisorsBuilder {
* @see #isEligibleBean
*/
public List<Advisor> buildAspectJAdvisors() {
List<String> aspectNames = this.aspectBeanNames;
List<String> aspectNames = null;
if (aspectNames == null) {
synchronized (this) {
aspectNames = this.aspectBeanNames;
if (aspectNames == null) {
List<Advisor> advisors = new LinkedList<Advisor>();
aspectNames = new LinkedList<String>();
String[] beanNames = BeanFactoryUtils.beanNamesForTypeIncludingAncestors(
this.beanFactory, Object.class, true, false);
for (String beanName : beanNames) {
if (!isEligibleBean(beanName)) {
continue;
}
// We must be careful not to instantiate beans eagerly as in this case they
// would be cached by the Spring container but would not have been weaved.
Class<?> beanType = this.beanFactory.getType(beanName);
if (beanType == null) {
continue;
}
if (this.advisorFactory.isAspect(beanType)) {
aspectNames.add(beanName);
AspectMetadata amd = new AspectMetadata(beanType, beanName);
if (amd.getAjType().getPerClause().getKind() == PerClauseKind.SINGLETON) {
MetadataAwareAspectInstanceFactory factory =
new BeanFactoryAspectInstanceFactory(this.beanFactory, beanName);
List<Advisor> classAdvisors = this.advisorFactory.getAdvisors(factory);
if (this.beanFactory.isSingleton(beanName)) {
this.advisorsCache.put(beanName, classAdvisors);
}
else {
this.aspectFactoryCache.put(beanName, factory);
}
advisors.addAll(classAdvisors);
synchronized (this) {
aspectNames = this.aspectBeanNames;
if (aspectNames == null) {
List<Advisor> advisors = new LinkedList<>();
aspectNames = new LinkedList<>();
String[] beanNames =
BeanFactoryUtils.beanNamesForTypeIncludingAncestors(this.beanFactory, Object.class, true, false);
for (String beanName : beanNames) {
if (!isEligibleBean(beanName)) {
continue;
}
// We must be careful not to instantiate beans eagerly as in this
// case they would be cached by the Spring container but would not
// have been weaved
Class<?> beanType = this.beanFactory.getType(beanName);
if (beanType == null) {
continue;
}
if (this.advisorFactory.isAspect(beanType)) {
aspectNames.add(beanName);
AspectMetadata amd = new AspectMetadata(beanType, beanName);
if (amd.getAjType().getPerClause().getKind() == PerClauseKind.SINGLETON) {
MetadataAwareAspectInstanceFactory factory =
new BeanFactoryAspectInstanceFactory(this.beanFactory, beanName);
List<Advisor> classAdvisors = this.advisorFactory.getAdvisors(factory);
if (this.beanFactory.isSingleton(beanName)) {
this.advisorsCache.put(beanName, classAdvisors);
}
else {
// Per target or per this.
if (this.beanFactory.isSingleton(beanName)) {
throw new IllegalArgumentException("Bean with name '" + beanName +
"' is a singleton, but aspect instantiation model is not singleton");
}
MetadataAwareAspectInstanceFactory factory =
new PrototypeAspectInstanceFactory(this.beanFactory, beanName);
this.aspectFactoryCache.put(beanName, factory);
advisors.addAll(this.advisorFactory.getAdvisors(factory));
}
advisors.addAll(classAdvisors);
}
else {
// Per target or per this.
if (this.beanFactory.isSingleton(beanName)) {
throw new IllegalArgumentException("Bean with name '" + beanName +
"' is a singleton, but aspect instantiation model is not singleton");
}
MetadataAwareAspectInstanceFactory factory =
new PrototypeAspectInstanceFactory(this.beanFactory, beanName);
this.aspectFactoryCache.put(beanName, factory);
advisors.addAll(this.advisorFactory.getAdvisors(factory));
}
}
this.aspectBeanNames = aspectNames;
return advisors;
}
this.aspectBeanNames = aspectNames;
return advisors;
}
}
if (aspectNames.isEmpty()) {
return Collections.emptyList();
}
List<Advisor> advisors = new LinkedList<Advisor>();
List<Advisor> advisors = new LinkedList<>();
for (String aspectName : aspectNames) {
List<Advisor> cachedAdvisors = this.advisorsCache.get(aspectName);
if (cachedAdvisors != null) {
@@ -1,11 +1,11 @@
/*
* Copyright 2002-2018 the original author or authors.
* Copyright 2002-2015 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.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
@@ -109,40 +109,14 @@ class InstantiationModelAwarePointcutAdvisorImpl
/**
* The pointcut for Spring AOP to use.
* Actual behaviour of the pointcut will change depending on the state of the advice.
* The pointcut for Spring AOP to use. Actual behaviour of the pointcut will change
* depending on the state of the advice.
*/
@Override
public Pointcut getPointcut() {
return this.pointcut;
}
@Override
public boolean isLazy() {
return this.lazy;
}
@Override
public synchronized boolean isAdviceInstantiated() {
return (this.instantiatedAdvice != null);
}
/**
* Lazily instantiate advice if necessary.
*/
@Override
public synchronized Advice getAdvice() {
if (this.instantiatedAdvice == null) {
this.instantiatedAdvice = instantiateAdvice(this.declaredPointcut);
}
return this.instantiatedAdvice;
}
private Advice instantiateAdvice(AspectJExpressionPointcut pcut) {
return this.aspectJAdvisorFactory.getAdvice(this.aspectJAdviceMethod, pcut,
this.aspectInstanceFactory, this.declarationOrder, this.aspectName);
}
/**
* This is only of interest for Spring AOP: AspectJ instantiation semantics
* are much richer. In AspectJ terminology, all a return of {@code true}
@@ -160,6 +134,33 @@ class InstantiationModelAwarePointcutAdvisorImpl
return this.aspectInstanceFactory.getAspectMetadata();
}
/**
* Lazily instantiate advice if necessary.
*/
@Override
public synchronized Advice getAdvice() {
if (this.instantiatedAdvice == null) {
this.instantiatedAdvice = instantiateAdvice(this.declaredPointcut);
}
return this.instantiatedAdvice;
}
@Override
public boolean isLazy() {
return this.lazy;
}
@Override
public synchronized boolean isAdviceInstantiated() {
return (this.instantiatedAdvice != null);
}
private Advice instantiateAdvice(AspectJExpressionPointcut pcut) {
return this.aspectJAdvisorFactory.getAdvice(this.aspectJAdviceMethod, pcut,
this.aspectInstanceFactory, this.declarationOrder, this.aspectName);
}
public MetadataAwareAspectInstanceFactory getAspectInstanceFactory() {
return this.aspectInstanceFactory;
}
@@ -212,26 +213,33 @@ class InstantiationModelAwarePointcutAdvisorImpl
}
else {
switch (aspectJAnnotation.getAnnotationType()) {
case AtPointcut:
case AtAround:
this.isBeforeAdvice = false;
this.isAfterAdvice = false;
break;
case AtBefore:
this.isBeforeAdvice = true;
this.isAfterAdvice = false;
break;
case AtAfter:
case AtAfterReturning:
case AtAfterThrowing:
this.isBeforeAdvice = false;
this.isAfterAdvice = true;
this.isBeforeAdvice = false;
break;
case AtAround:
case AtPointcut:
this.isAfterAdvice = false;
this.isBeforeAdvice = false;
break;
case AtBefore:
this.isAfterAdvice = false;
this.isBeforeAdvice = true;
}
}
}
@Override
public String toString() {
return "InstantiationModelAwarePointcutAdvisor: expression [" + getDeclaredPointcut().getExpression() +
"]; advice method [" + this.aspectJAdviceMethod + "]; perClauseKind=" +
this.aspectInstanceFactory.getAspectMetadata().getAjType().getPerClause().getKind();
}
private void readObject(ObjectInputStream inputStream) throws IOException, ClassNotFoundException {
inputStream.defaultReadObject();
try {
@@ -242,18 +250,11 @@ class InstantiationModelAwarePointcutAdvisorImpl
}
}
@Override
public String toString() {
return "InstantiationModelAwarePointcutAdvisor: expression [" + getDeclaredPointcut().getExpression() +
"]; advice method [" + this.aspectJAdviceMethod + "]; perClauseKind=" +
this.aspectInstanceFactory.getAspectMetadata().getAjType().getPerClause().getKind();
}
/**
* Pointcut implementation that changes its behaviour when the advice is instantiated.
* Note that this is a <i>dynamic</i> pointcut; otherwise it might be optimized out
* if it does not at first match statically.
* Note that this is a <i>dynamic</i> pointcut. Otherwise it might
* be optimized out if it does not at first match statically.
*/
private class PerTargetInstantiationModelPointcut extends DynamicMethodMatcherPointcut {
@@ -263,9 +264,8 @@ class InstantiationModelAwarePointcutAdvisorImpl
private LazySingletonAspectInstanceFactoryDecorator aspectInstanceFactory;
public PerTargetInstantiationModelPointcut(AspectJExpressionPointcut declaredPointcut,
private PerTargetInstantiationModelPointcut(AspectJExpressionPointcut declaredPointcut,
Pointcut preInstantiationPointcut, MetadataAwareAspectInstanceFactory aspectInstanceFactory) {
this.declaredPointcut = declaredPointcut;
this.preInstantiationPointcut = preInstantiationPointcut;
if (aspectInstanceFactory instanceof LazySingletonAspectInstanceFactoryDecorator) {
@@ -275,8 +275,7 @@ class InstantiationModelAwarePointcutAdvisorImpl
@Override
public boolean matches(Method method, Class<?> targetClass) {
// We're either instantiated and matching on declared pointcut,
// or uninstantiated matching on either pointcut...
// We're either instantiated and matching on declared pointcut, or uninstantiated matching on either pointcut
return (isAspectMaterialized() && this.declaredPointcut.matches(method, targetClass)) ||
this.preInstantiationPointcut.getMethodMatcher().matches(method, targetClass);
}
@@ -5,7 +5,7 @@
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
@@ -48,15 +48,9 @@ public class LazySingletonAspectInstanceFactoryDecorator implements MetadataAwar
@Override
public Object getAspectInstance() {
if (this.materialized == null) {
Object mutex = this.maaif.getAspectCreationMutex();
if (mutex == null) {
this.materialized = this.maaif.getAspectInstance();
}
else {
synchronized (mutex) {
if (this.materialized == null) {
this.materialized = this.maaif.getAspectInstance();
}
synchronized (this.maaif.getAspectCreationMutex()) {
if (this.materialized == null) {
this.materialized = this.maaif.getAspectInstance();
}
}
}
@@ -5,7 +5,7 @@
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
@@ -41,7 +41,7 @@ public interface MetadataAwareAspectInstanceFactory extends AspectInstanceFactor
/**
* Return the best possible creation mutex for this factory.
* @return the mutex object (may be {@code null} for no mutex to use)
* @return the mutex object (never {@code null})
* @since 4.3
*/
Object getAspectCreationMutex();
@@ -5,7 +5,7 @@
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
@@ -5,7 +5,7 @@
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
@@ -1,11 +1,11 @@
/*
* Copyright 2002-2020 the original author or authors.
* Copyright 2002-2016 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.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
@@ -20,9 +20,9 @@ import java.io.Serializable;
import java.lang.annotation.Annotation;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.LinkedList;
import java.util.List;
import org.aopalliance.aop.Advice;
@@ -46,7 +46,6 @@ import org.springframework.aop.aspectj.AspectJMethodBeforeAdvice;
import org.springframework.aop.aspectj.DeclareParentsAdvisor;
import org.springframework.aop.framework.AopConfigException;
import org.springframework.aop.support.DefaultPointcutAdvisor;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.core.annotation.AnnotationUtils;
import org.springframework.core.convert.converter.Converter;
import org.springframework.core.convert.converter.ConvertingComparator;
@@ -73,18 +72,19 @@ public class ReflectiveAspectJAdvisorFactory extends AbstractAspectJAdvisorFacto
private static final Comparator<Method> METHOD_COMPARATOR;
static {
CompoundComparator<Method> comparator = new CompoundComparator<Method>();
comparator.addComparator(new ConvertingComparator<Method, Annotation>(
new InstanceComparator<Annotation>(
CompoundComparator<Method> comparator = new CompoundComparator<>();
comparator.addComparator(new ConvertingComparator<>(
new InstanceComparator<>(
Around.class, Before.class, After.class, AfterReturning.class, AfterThrowing.class),
new Converter<Method, Annotation>() {
@Override
public Annotation convert(Method method) {
AspectJAnnotation<?> ann = AbstractAspectJAdvisorFactory.findAspectJAnnotationOnMethod(method);
return (ann != null ? ann.getAnnotation() : null);
AspectJAnnotation<?> annotation =
AbstractAspectJAdvisorFactory.findAspectJAnnotationOnMethod(method);
return (annotation != null ? annotation.getAnnotation() : null);
}
}));
comparator.addComparator(new ConvertingComparator<Method, String>(
comparator.addComparator(new ConvertingComparator<>(
new Converter<Method, String>() {
@Override
public String convert(Method method) {
@@ -95,30 +95,6 @@ public class ReflectiveAspectJAdvisorFactory extends AbstractAspectJAdvisorFacto
}
private final BeanFactory beanFactory;
/**
* Create a new {@code ReflectiveAspectJAdvisorFactory}.
*/
public ReflectiveAspectJAdvisorFactory() {
this(null);
}
/**
* Create a new {@code ReflectiveAspectJAdvisorFactory}, propagating the given
* {@link BeanFactory} to the created {@link AspectJExpressionPointcut} instances,
* for bean pointcut handling as well as consistent {@link ClassLoader} resolution.
* @param beanFactory the BeanFactory to propagate (may be {@code null}}
* @since 4.3.6
* @see AspectJExpressionPointcut#setBeanFactory
* @see org.springframework.beans.factory.config.ConfigurableBeanFactory#getBeanClassLoader()
*/
public ReflectiveAspectJAdvisorFactory(BeanFactory beanFactory) {
this.beanFactory = beanFactory;
}
@Override
public List<Advisor> getAdvisors(MetadataAwareAspectInstanceFactory aspectInstanceFactory) {
Class<?> aspectClass = aspectInstanceFactory.getAspectMetadata().getAspectClass();
@@ -130,7 +106,7 @@ public class ReflectiveAspectJAdvisorFactory extends AbstractAspectJAdvisorFacto
MetadataAwareAspectInstanceFactory lazySingletonAspectInstanceFactory =
new LazySingletonAspectInstanceFactoryDecorator(aspectInstanceFactory);
List<Advisor> advisors = new ArrayList<Advisor>();
List<Advisor> advisors = new LinkedList<>();
for (Method method : getAdvisorMethods(aspectClass)) {
Advisor advisor = getAdvisor(method, lazySingletonAspectInstanceFactory, advisors.size(), aspectName);
if (advisor != null) {
@@ -156,7 +132,7 @@ public class ReflectiveAspectJAdvisorFactory extends AbstractAspectJAdvisorFacto
}
private List<Method> getAdvisorMethods(Class<?> aspectClass) {
final List<Method> methods = new ArrayList<Method>();
final List<Method> methods = new LinkedList<>();
ReflectionUtils.doWithMethods(aspectClass, new ReflectionUtils.MethodCallback() {
@Override
public void doWith(Method method) throws IllegalArgumentException {
@@ -175,7 +151,7 @@ public class ReflectiveAspectJAdvisorFactory extends AbstractAspectJAdvisorFacto
* for the given introduction field.
* <p>Resulting Advisors will need to be evaluated for targets.
* @param introductionField the field to introspect
* @return the Advisor instance, or {@code null} if not an Advisor
* @return {@code null} if not an Advisor
*/
private Advisor getDeclareParentsAdvisor(Field introductionField) {
DeclareParents declareParents = introductionField.getAnnotation(DeclareParents.class);
@@ -185,7 +161,9 @@ public class ReflectiveAspectJAdvisorFactory extends AbstractAspectJAdvisorFacto
}
if (DeclareParents.class == declareParents.defaultImpl()) {
throw new IllegalStateException("'defaultImpl' attribute must be set on DeclareParents");
// This is what comes back if it wasn't set. This seems bizarre...
// TODO this restriction possibly should be relaxed
throw new IllegalStateException("defaultImpl must be set on DeclareParents");
}
return new DeclareParentsAdvisor(
@@ -219,7 +197,6 @@ public class ReflectiveAspectJAdvisorFactory extends AbstractAspectJAdvisorFacto
AspectJExpressionPointcut ajexp =
new AspectJExpressionPointcut(candidateAspectClass, new String[0], new Class<?>[0]);
ajexp.setExpression(aspectJAnnotation.getPointcutExpression());
ajexp.setBeanFactory(this.beanFactory);
return ajexp;
}
@@ -252,15 +229,6 @@ public class ReflectiveAspectJAdvisorFactory extends AbstractAspectJAdvisorFacto
AbstractAspectJAdvice springAdvice;
switch (aspectJAnnotation.getAnnotationType()) {
case AtPointcut:
if (logger.isDebugEnabled()) {
logger.debug("Processing pointcut '" + candidateAdviceMethod.getName() + "'");
}
return null;
case AtAround:
springAdvice = new AspectJAroundAdvice(
candidateAdviceMethod, expressionPointcut, aspectInstanceFactory);
break;
case AtBefore:
springAdvice = new AspectJMethodBeforeAdvice(
candidateAdviceMethod, expressionPointcut, aspectInstanceFactory);
@@ -285,6 +253,15 @@ public class ReflectiveAspectJAdvisorFactory extends AbstractAspectJAdvisorFacto
springAdvice.setThrowingName(afterThrowingAnnotation.throwing());
}
break;
case AtAround:
springAdvice = new AspectJAroundAdvice(
candidateAdviceMethod, expressionPointcut, aspectInstanceFactory);
break;
case AtPointcut:
if (logger.isDebugEnabled()) {
logger.debug("Processing pointcut '" + candidateAdviceMethod.getName() + "'");
}
return null;
default:
throw new UnsupportedOperationException(
"Unsupported advice type on method: " + candidateAdviceMethod);
@@ -298,7 +275,6 @@ public class ReflectiveAspectJAdvisorFactory extends AbstractAspectJAdvisorFacto
springAdvice.setArgumentNamesFromStringArray(argNames);
}
springAdvice.calculateArgumentBindings();
return springAdvice;
}
@@ -5,7 +5,7 @@
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
@@ -5,7 +5,7 @@
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
@@ -1,11 +1,11 @@
/*
* Copyright 2002-2013 the original author or authors.
* Copyright 2002-2016 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.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
@@ -68,7 +68,7 @@ public class AspectJAwareAdvisorAutoProxyCreator extends AbstractAdvisorAutoProx
@SuppressWarnings("unchecked")
protected List<Advisor> sortAdvisors(List<Advisor> advisors) {
List<PartiallyComparableAdvisorHolder> partiallyComparableAdvisors =
new ArrayList<PartiallyComparableAdvisorHolder>(advisors.size());
new ArrayList<>(advisors.size());
for (Advisor element : advisors) {
partiallyComparableAdvisors.add(
new PartiallyComparableAdvisorHolder(element, DEFAULT_PRECEDENCE_COMPARATOR));
@@ -76,7 +76,7 @@ public class AspectJAwareAdvisorAutoProxyCreator extends AbstractAdvisorAutoProx
List<PartiallyComparableAdvisorHolder> sorted =
PartialOrder.sort(partiallyComparableAdvisors);
if (sorted != null) {
List<Advisor> result = new ArrayList<Advisor>(advisors.size());
List<Advisor> result = new ArrayList<>(advisors.size());
for (PartiallyComparableAdvisorHolder pcAdvisor : sorted) {
result.add(pcAdvisor.getAdvisor());
}
@@ -1,11 +1,11 @@
/*
* Copyright 2002-2020 the original author or authors.
* Copyright 2002-2015 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.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
@@ -136,8 +136,14 @@ class AspectJPrecedenceComparator implements Comparator<Advisor> {
}
private int getAspectDeclarationOrder(Advisor anAdvisor) {
AspectJPrecedenceInformation precedenceInfo = AspectJAopUtils.getAspectJPrecedenceInformationFor(anAdvisor);
return (precedenceInfo != null ? precedenceInfo.getDeclarationOrder() : 0);
AspectJPrecedenceInformation precedenceInfo =
AspectJAopUtils.getAspectJPrecedenceInformationFor(anAdvisor);
if (precedenceInfo != null) {
return precedenceInfo.getDeclarationOrder();
}
else {
return 0;
}
}
}
@@ -1,11 +1,11 @@
/*
* Copyright 2002-2016 the original author or authors.
* Copyright 2002-2012 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.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
@@ -71,7 +71,7 @@ public abstract class AbstractInterceptorDrivenBeanDefinitionDecorator implement
BeanDefinition interceptorDefinition = createInterceptorDefinition(node);
// generate name and register the interceptor
String interceptorName = existingBeanName + '.' + getInterceptorNameSuffix(interceptorDefinition);
String interceptorName = existingBeanName + "." + getInterceptorNameSuffix(interceptorDefinition);
BeanDefinitionReaderUtils.registerBeanDefinition(
new BeanDefinitionHolder(interceptorDefinition, interceptorName), registry);
@@ -1,11 +1,11 @@
/*
* Copyright 2002-2020 the original author or authors.
* Copyright 2002-2012 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.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
@@ -30,14 +30,13 @@ public class AdviceEntry implements ParseState.Entry {
/**
* Create a new {@code AdviceEntry} instance.
* @param kind the kind of advice represented by this entry (before, after, around)
* Creates a new instance of the {@link AdviceEntry} class.
* @param kind the kind of advice represented by this entry (before, after, around, etc.)
*/
public AdviceEntry(String kind) {
this.kind = kind;
}
@Override
public String toString() {
return "Advice (" + this.kind + ")";
@@ -5,7 +5,7 @@
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
@@ -1,11 +1,11 @@
/*
* Copyright 2002-2020 the original author or authors.
* Copyright 2002-2012 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.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
@@ -30,14 +30,13 @@ public class AdvisorEntry implements ParseState.Entry {
/**
* Create a new {@code AdvisorEntry} instance.
* Creates a new instance of the {@link AdvisorEntry} class.
* @param name the bean name of the advisor
*/
public AdvisorEntry(String name) {
this.name = name;
}
@Override
public String toString() {
return "Advisor '" + this.name + "'";
@@ -1,11 +1,11 @@
/*
* Copyright 2002-2018 the original author or authors.
* Copyright 2002-2016 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.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
@@ -31,10 +31,11 @@ import org.springframework.util.Assert;
/**
* Utility class for handling registration of AOP auto-proxy creators.
*
* <p>Only a single auto-proxy creator should be registered yet multiple concrete
* implementations are available. This class provides a simple escalation protocol,
* allowing a caller to request a particular auto-proxy creator and know that creator,
* <i>or a more capable variant thereof</i>, will be registered as a post-processor.
* <p>Only a single auto-proxy creator can be registered yet multiple concrete
* implementations are available. Therefore this class wraps a simple escalation
* protocol, allowing classes to request a particular auto-proxy creator and know
* that class, {@code or a subclass thereof}, will eventually be resident
* in the application context.
*
* @author Rob Harrop
* @author Juergen Hoeller
@@ -53,10 +54,12 @@ public abstract class AopConfigUtils {
/**
* Stores the auto proxy creator classes in escalation order.
*/
private static final List<Class<?>> APC_PRIORITY_LIST = new ArrayList<Class<?>>(3);
private static final List<Class<?>> APC_PRIORITY_LIST = new ArrayList<>();
/**
* Setup the escalation list.
*/
static {
// Set up the escalation list...
APC_PRIORITY_LIST.add(InfrastructureAdvisorAutoProxyCreator.class);
APC_PRIORITY_LIST.add(AspectJAwareAdvisorAutoProxyCreator.class);
APC_PRIORITY_LIST.add(AnnotationAwareAspectJAutoProxyCreator.class);
@@ -104,7 +107,6 @@ public abstract class AopConfigUtils {
private static BeanDefinition registerOrEscalateApcAsRequired(Class<?> cls, BeanDefinitionRegistry registry, Object source) {
Assert.notNull(registry, "BeanDefinitionRegistry must not be null");
if (registry.containsBeanDefinition(AUTO_PROXY_CREATOR_BEAN_NAME)) {
BeanDefinition apcDefinition = registry.getBeanDefinition(AUTO_PROXY_CREATOR_BEAN_NAME);
if (!cls.getName().equals(apcDefinition.getBeanClassName())) {
@@ -116,7 +118,6 @@ public abstract class AopConfigUtils {
}
return null;
}
RootBeanDefinition beanDefinition = new RootBeanDefinition(cls);
beanDefinition.setSource(source);
beanDefinition.getPropertyValues().add("order", Ordered.HIGHEST_PRECEDENCE);
@@ -1,11 +1,11 @@
/*
* Copyright 2002-2020 the original author or authors.
* Copyright 2002-2012 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.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
@@ -61,12 +61,12 @@ public class AopNamespaceHandler extends NamespaceHandlerSupport {
*/
@Override
public void init() {
// In 2.0 XSD as well as in 2.5+ XSDs
// In 2.0 XSD as well as in 2.1 XSD.
registerBeanDefinitionParser("config", new ConfigBeanDefinitionParser());
registerBeanDefinitionParser("aspectj-autoproxy", new AspectJAutoProxyBeanDefinitionParser());
registerBeanDefinitionDecorator("scoped-proxy", new ScopedProxyBeanDefinitionDecorator());
// Only in 2.0 XSD: moved to context namespace in 2.5+
// Only in 2.0 XSD: moved to context namespace as of 2.1
registerBeanDefinitionParser("spring-configured", new SpringConfiguredBeanDefinitionParser());
}
@@ -1,11 +1,11 @@
/*
* Copyright 2002-2018 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.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
@@ -27,11 +27,11 @@ import org.springframework.beans.factory.xml.ParserContext;
* Utility class for handling registration of auto-proxy creators used internally
* by the '{@code aop}' namespace tags.
*
* <p>Only a single auto-proxy creator should be registered and multiple configuration
* elements may wish to register different concrete implementations. As such this class
* delegates to {@link AopConfigUtils} which provides a simple escalation protocol.
* Callers may request a particular auto-proxy creator and know that creator,
* <i>or a more capable variant thereof</i>, will be registered as a post-processor.
* <p>Only a single auto-proxy creator can be registered and multiple tags may wish
* to register different concrete implementations. As such this class delegates to
* {@link AopConfigUtils} which wraps a simple escalation protocol. Therefore classes
* may request a particular auto-proxy creator and know that class, <i>or a subclass
* thereof</i>, will eventually be resident in the application context.
*
* @author Rob Harrop
* @author Juergen Hoeller
@@ -81,11 +81,11 @@ public abstract class AopNamespaceUtils {
private static void useClassProxyingIfNecessary(BeanDefinitionRegistry registry, Element sourceElement) {
if (sourceElement != null) {
boolean proxyTargetClass = Boolean.parseBoolean(sourceElement.getAttribute(PROXY_TARGET_CLASS_ATTRIBUTE));
boolean proxyTargetClass = Boolean.valueOf(sourceElement.getAttribute(PROXY_TARGET_CLASS_ATTRIBUTE));
if (proxyTargetClass) {
AopConfigUtils.forceAutoProxyCreatorToUseClassProxying(registry);
}
boolean exposeProxy = Boolean.parseBoolean(sourceElement.getAttribute(EXPOSE_PROXY_ATTRIBUTE));
boolean exposeProxy = Boolean.valueOf(sourceElement.getAttribute(EXPOSE_PROXY_ATTRIBUTE));
if (exposeProxy) {
AopConfigUtils.forceAutoProxyCreatorToExposeProxy(registry);
}
@@ -94,8 +94,9 @@ public abstract class AopNamespaceUtils {
private static void registerComponentIfNecessary(BeanDefinition beanDefinition, ParserContext parserContext) {
if (beanDefinition != null) {
parserContext.registerComponent(
new BeanComponentDefinition(beanDefinition, AopConfigUtils.AUTO_PROXY_CREATOR_BEAN_NAME));
BeanComponentDefinition componentDefinition =
new BeanComponentDefinition(beanDefinition, AopConfigUtils.AUTO_PROXY_CREATOR_BEAN_NAME);
parserContext.registerComponent(componentDefinition);
}
}
@@ -5,7 +5,7 @@
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
@@ -1,11 +1,11 @@
/*
* Copyright 2002-2020 the original author or authors.
* Copyright 2002-2007 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.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
@@ -34,7 +34,7 @@ public class AspectEntry implements ParseState.Entry {
/**
* Create a new {@code AspectEntry} instance.
* Create a new AspectEntry.
* @param id the id of the aspect element
* @param ref the bean name referenced by this aspect element
*/
@@ -43,7 +43,6 @@ public class AspectEntry implements ParseState.Entry {
this.ref = ref;
}
@Override
public String toString() {
return "Aspect: " + (StringUtils.hasLength(this.id) ? "id='" + this.id + "'" : "ref='" + this.ref + "'");

Some files were not shown because too many files have changed in this diff Show More